minennick
minennick

Reputation: 91

ActiveModel::MissingAttributeError (can't write unknown attribute `user_id`)

I have problems with my comments when my app is deployed. Locally everything is working. The logs from heroku says:

ActiveModel::MissingAttributeError (can't write unknown attribute `user_id`):
2018-01-02T15:52:43.461794+00:00 app[web.1]: [79cd7190-e2d9-4dd0-bf71-
709552e5c6e5] app/controllers/comments_controller.rb:15:in `create'

I have no ideas what is occuring the error. Maybe some database thing?

My CommentsController

class CommentsController < ApplicationController

def create 
    @post =Post.find(params[:post_id])
    @comment [email protected](params[:comment].permit(:name, :body).merge(user: current_user))
    redirect_to post_path(@post)
end


def destroy 

    @post = Post.find(params[:post_id])
    @comment= @post.comments.find(params[:id])
    if current_user.id == @comment.user_id 
        @comment.destroy
    end
    redirect_to post_path(@post)
end
end

My Models

class User < ApplicationRecord
 has_many :posts

 devise :database_authenticatable, :registerable,
        :recoverable, :rememberable, :trackable, :validatable
end

class Post < ApplicationRecord
  belongs_to :user, optional: true
  has_many :comments, dependent: :destroy

  validates :title, presence: true, length: {minimum: 5}
  validates :body, presence: true

end

class Comment < ApplicationRecord
 belongs_to :post
 belongs_to :user
end

My migration-file

class CreateComments < ActiveRecord::Migration[5.1]
 def change
 create_table :comments do |t|
   t.string :name
   t.text :body
   t.references :post, index: true

   t.timestamps
 end
 end
end

if you need more code or have any ideas please let me know

EDIT: if i add a user_id column i get a SQLite3::SQLException: duplicate column name: user_id: ALTER TABLE "comments" ADD "user_id" integer error

My schema.rb

`create_table "comments", force: :cascade do |t|
t.string "name"
t.text "body"
t.integer "post_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "user_id"
t.index ["post_id"], name: "index_comments_on_post_id"
end

create_table "posts", force: :cascade do |t|
t.string "title"
t.text "body"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "image_file_name"
t.string "image_content_type"
t.integer "image_file_size"
t.datetime "image_updated_at"
t.string "theme"
t.integer "user_id"
end

create_table "users", force: :cascade do |t|
t.string "email", default: "", null: false
t.string "encrypted_password", default: "", null: false
t.string "reset_password_token"
t.datetime "reset_password_sent_at"
t.datetime "remember_created_at"
t.integer "sign_in_count", default: 0, null: false
t.datetime "current_sign_in_at"
t.datetime "last_sign_in_at"
t.string "current_sign_in_ip"
t.string "last_sign_in_ip"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["email"], name: "index_users_on_email", unique: true
t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
end

Upvotes: 4

Views: 13564

Answers (3)

Manishh
Manishh

Reputation: 1484

Your migration have missing

t.references :user, index: true

So you need to add user_id column within comments table

Update : It seems like you have some migration problem. I suggest you to check for rake db:migrate:status comment and look for any down migration. Once all are up then just run rake db:migrate:down VERSION='VERSION_NUMBER_HERE' and add your user t.references :user, index: true to the same migration and migrate.

PS: Change existing migration if and only if you have not pushed it.

Upvotes: 1

SRack
SRack

Reputation: 12203

You'll need to add a user_id column to your comments table. The belongs_to requires this. You're also going to need a post_id column, and user_id for your posts table to.

You can customise the column name, but the convention is to use the format parent_table_id.

Here's the key quote, from the docs:

Associations are implemented using macro-style calls, so that you can declaratively add features to your models. For example, by declaring that one model belongs_to another, you instruct Rails to maintain Primary Key-Foreign Key information between instances of the two models, and you also get a number of utility methods added to your model.

This means, for example, if your first user has an id of 1, all of their comments and posts will have a user_id value of 1, which does the actual tying together of the records.

Here's an example migration with the relevant line included:

def change 
  create_table :comments do |t|
    ...
    t.belongs_to :user, index: true
    ...
  end
end

Does that make sense? Let me know if you've any questions and I can update as needed :)

Upvotes: 7

SteveTurczyn
SteveTurczyn

Reputation: 36860

You need to add user_id

Create the migration with

rails g migration AddUserIdToComment user:references

Then do

rake db:migrate

And you should be fine.

Upvotes: 1

Related Questions