ActiveModel :: MissingAttributeError:无法写入未知属性`user_id`

我正在尝试实施“评论”function,作为我正在建设的项目的一部分。

在本课程的早些时候,我们创建了一个评论表,并让Faker gem生成虚假评论。

我的说明如下:

注释必须与用户关联,因此将user_id外键添加到comments表中。 记得也要添加一个索引;

更新用户模型,以便您可以调用user.comments和Comment模型,以便您可以调用comment.user;

运行db:reset时,修改seeds.rb文件以创建有效注释;

最初我试图运行我的rails generate命令,但一直遇到这个错误:

▶ rake db:migrate == 20150508143445 CreateComments: migrating =================================== -- create_table(:comments) rake aborted! StandardError: An error has occurred, this and all later migrations canceled: SQLite3::SQLException: table "comments" already exists: CREATE TABLE "comments" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "description" text, "created_at" datetime NOT NULL, "updated_at" datetime NOT NULL) /Users/jon/code/bloccit/db/migrate/20150508143445_create_comments.rb:3:in `change' -e:1:in `' ActiveRecord::StatementInvalid: SQLite3::SQLException: table "comments" already exists: CREATE TABLE "comments" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "description" text, "created_at" datetime NOT NULL, "updated_at" datetime NOT NULL) /Users/jon/code/bloccit/db/migrate/20150508143445_create_comments.rb:3:in `change' -e:1:in `' SQLite3::SQLException: table "comments" already exists /Users/jon/code/bloccit/db/migrate/20150508143445_create_comments.rb:3:in `change' -e:1:in `' Tasks: TOP => db:migrate (See full trace by running task with --trace) 

所以我发现我需要从课程开始时删除旧表。 我在控制台中这样做了。

 ActiveRecord::Base.connection.execute("drop table comments") 

它似乎工作。 然后我能够在终端中运行这些。

 ▶ rake db:migrate == 20150508143445 CreateComments: migrating =================================== -- create_table(:comments) -> 0.0015s == 20150508143445 CreateComments: migrated (0.0016s) ========================== == 20150508152354 DropComments: migrating ===================================== == 20150508152354 DropComments: migrated (0.0000s) ============================ ▶ rails g migration AddCommentToUsers commed_id:integer:index invoke active_record create db/migrate/20150508155200_add_comment_to_users.rb ▶ rake db:migrate == 20150508155200 AddCommentToUsers: migrating ================================ -- add_column(:users, :commed_id, :integer) -> 0.0010s -- add_index(:users, :commed_id) -> 0.0012s == 20150508155200 AddCommentToUsers: migrated (0.0023s) ======================= 

车型/ comment.rb

 class Comment < ActiveRecord::Base belongs_to :user end 

车型/ user.rb

 class User < ActiveRecord::Base # Include default devise modules. Others available are: # :confirmable, :lockable, :timeoutable and :omniauthable devise :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable, :confirmable has_many :posts has_many :comments # CarrierWave method for attribute functionality mount_uploader :avatar, AvatarUploader # These methods check the role of a user in the database def admin? role == 'admin' end def moderator? role == 'moderator' end end 

迁移/ create_comments.rb

 class CreateComments < ActiveRecord::Migration def change create_table :comments do |t| t.text :description t.timestamps null: false end end end 

迁移/ add_comment_to_users.rb

 class AddCommentToUsers < ActiveRecord::Migration def change add_column :users, :commed_id, :integer add_index :users, :commed_id end end 

在我的种子里。我改变了

 # Create Comments 50.times do Comment.create!( # user: users.sample, # we have not yet associated Users with Comments post: posts.sample, description: Faker::Lorem.paragraph ) end 

 # Create Comments 50.times do Comment.create!( user: users.sample, description: Faker::Lorem.paragraph ) end 

现在,当我运行rake db:reset时出现此错误。

 ▶ rake db:reset -- create_table("advertisements", {:force=>:cascade}) -> 0.0047s -- create_table("answers", {:force=>:cascade}) -> 0.0010s -- add_index("answers", ["question_id"], {:name=>"index_answers_on_question_id"}) -> 0.0014s -- create_table("comments", {:force=>:cascade}) -> 0.0010s -- create_table("posts", {:force=>:cascade}) -> 0.0010s -- add_index("posts", ["topic_id"], {:name=>"index_posts_on_topic_id"}) -> 0.0010s -- add_index("posts", ["user_id"], {:name=>"index_posts_on_user_id"}) -> 0.0014s -- create_table("questions", {:force=>:cascade}) -> 0.0010s -- create_table("summaries", {:force=>:cascade}) -> 0.0010s -- add_index("summaries", ["post_id"], {:name=>"index_summaries_on_post_id"}) -> 0.0010s -- create_table("topics", {:force=>:cascade}) -> 0.0036s -- create_table("users", {:force=>:cascade}) -> 0.0015s -- add_index("users", ["commed_id"], {:name=>"index_users_on_commed_id"}) -> 0.0009s -- add_index("users", ["comment_id"], {:name=>"index_users_on_comment_id"}) -> 0.0012s -- add_index("users", ["email"], {:name=>"index_users_on_email", :unique=>true}) -> 0.0015s -- add_index("users", ["reset_password_token"], {:name=>"index_users_on_reset_password_token", :unique=>true}) -> 0.0017s -- initialize_schema_migrations_table() -> 0.0034s rake aborted! ActiveModel::MissingAttributeError: can't write unknown attribute `user_id` /Users/jon/code/Bloccit/db/seeds.rb:45:in `block in ' /Users/jon/code/Bloccit/db/seeds.rb:44:in `times' /Users/jon/code/Bloccit/db/seeds.rb:44:in `' -e:1:in `' Tasks: TOP => db:setup => db:seed (See full trace by running task with --trace) 

这是完整的堆栈跟踪:

 ActiveModel::MissingAttributeError: can't write unknown attribute `user_id` /Users/jon/.rvm/rubies/ruby-2.2.1/lib/ruby/gems/2.2.0/gems/activerecord-4.2.1/lib/active_record/attribute.rb:138:in `with_value_from_database' /Users/jon/.rvm/rubies/ruby-2.2.1/lib/ruby/gems/2.2.0/gems/activerecord-4.2.1/lib/active_record/attribute_set.rb:39:in `write_from_user' /Users/jon/.rvm/rubies/ruby-2.2.1/lib/ruby/gems/2.2.0/gems/activerecord-4.2.1/lib/active_record/attribute_methods/write.rb:74:in `write_attribute_with_type_cast' /Users/jon/.rvm/rubies/ruby-2.2.1/lib/ruby/gems/2.2.0/gems/activerecord-4.2.1/lib/active_record/attribute_methods/write.rb:56:in `write_attribute' /Users/jon/.rvm/rubies/ruby-2.2.1/lib/ruby/gems/2.2.0/gems/activerecord-4.2.1/lib/active_record/attribute_methods/dirty.rb:96:in `write_attribute' /Users/jon/.rvm/rubies/ruby-2.2.1/lib/ruby/gems/2.2.0/gems/activerecord-4.2.1/lib/active_record/attribute_methods.rb:373:in `[]=' /Users/jon/.rvm/rubies/ruby-2.2.1/lib/ruby/gems/2.2.0/gems/activerecord-4.2.1/lib/active_record/associations/belongs_to_association.rb:83:in `replace_keys' /Users/jon/.rvm/rubies/ruby-2.2.1/lib/ruby/gems/2.2.0/gems/activerecord-4.2.1/lib/active_record/associations/belongs_to_association.rb:14:in `replace' /Users/jon/.rvm/rubies/ruby-2.2.1/lib/ruby/gems/2.2.0/gems/activerecord-4.2.1/lib/active_record/associations/singular_association.rb:17:in `writer' /Users/jon/.rvm/rubies/ruby-2.2.1/lib/ruby/gems/2.2.0/gems/activerecord-4.2.1/lib/active_record/associations/builder/association.rb:123:in `user=' /Users/jon/.rvm/rubies/ruby-2.2.1/lib/ruby/gems/2.2.0/gems/activerecord-4.2.1/lib/active_record/attribute_assignment.rb:54:in `public_send' /Users/jon/.rvm/rubies/ruby-2.2.1/lib/ruby/gems/2.2.0/gems/activerecord-4.2.1/lib/active_record/attribute_assignment.rb:54:in `_assign_attribute' /Users/jon/.rvm/rubies/ruby-2.2.1/lib/ruby/gems/2.2.0/gems/activerecord-4.2.1/lib/active_record/attribute_assignment.rb:41:in `block in assign_attributes' /Users/jon/.rvm/rubies/ruby-2.2.1/lib/ruby/gems/2.2.0/gems/activerecord-4.2.1/lib/active_record/attribute_assignment.rb:35:in `each' /Users/jon/.rvm/rubies/ruby-2.2.1/lib/ruby/gems/2.2.0/gems/activerecord-4.2.1/lib/active_record/attribute_assignment.rb:35:in `assign_attributes' /Users/jon/.rvm/rubies/ruby-2.2.1/lib/ruby/gems/2.2.0/gems/activerecord-4.2.1/lib/active_record/core.rb:559:in `init_attributes' /Users/jon/.rvm/rubies/ruby-2.2.1/lib/ruby/gems/2.2.0/gems/activerecord-4.2.1/lib/active_record/core.rb:281:in `initialize' /Users/jon/.rvm/rubies/ruby-2.2.1/lib/ruby/gems/2.2.0/gems/activerecord-4.2.1/lib/active_record/inheritance.rb:61:in `new' /Users/jon/.rvm/rubies/ruby-2.2.1/lib/ruby/gems/2.2.0/gems/activerecord-4.2.1/lib/active_record/inheritance.rb:61:in `new' /Users/jon/.rvm/rubies/ruby-2.2.1/lib/ruby/gems/2.2.0/gems/activerecord-4.2.1/lib/active_record/persistence.rb:50:in `create!' /Users/jon/code/Bloccit/db/seeds.rb:45:in `block in ' /Users/jon/code/Bloccit/db/seeds.rb:44:in `times' /Users/jon/code/Bloccit/db/seeds.rb:44:in `' /Users/jon/.rvm/rubies/ruby-2.2.1/lib/ruby/gems/2.2.0/gems/activesupport-4.2.1/lib/active_support/dependencies.rb:268:in `load' /Users/jon/.rvm/rubies/ruby-2.2.1/lib/ruby/gems/2.2.0/gems/activesupport-4.2.1/lib/active_support/dependencies.rb:268:in `block in load' /Users/jon/.rvm/rubies/ruby-2.2.1/lib/ruby/gems/2.2.0/gems/activesupport-4.2.1/lib/active_support/dependencies.rb:240:in `load_dependency' /Users/jon/.rvm/rubies/ruby-2.2.1/lib/ruby/gems/2.2.0/gems/activesupport-4.2.1/lib/active_support/dependencies.rb:268:in `load' /Users/jon/.rvm/rubies/ruby-2.2.1/lib/ruby/gems/2.2.0/gems/railties-4.2.1/lib/rails/engine.rb:547:in `load_seed' /Users/jon/.rvm/rubies/ruby-2.2.1/lib/ruby/gems/2.2.0/gems/activerecord-4.2.1/lib/active_record/tasks/database_tasks.rb:250:in `load_seed' /Users/jon/.rvm/rubies/ruby-2.2.1/lib/ruby/gems/2.2.0/gems/activerecord-4.2.1/lib/active_record/railties/databases.rake:180:in `block (2 levels) in ' /Users/jon/.rvm/rubies/ruby-2.2.1/lib/ruby/2.2.0/rake/task.rb:240:in `call' /Users/jon/.rvm/rubies/ruby-2.2.1/lib/ruby/2.2.0/rake/task.rb:240:in `block in execute' /Users/jon/.rvm/rubies/ruby-2.2.1/lib/ruby/2.2.0/rake/task.rb:235:in `each' /Users/jon/.rvm/rubies/ruby-2.2.1/lib/ruby/2.2.0/rake/task.rb:235:in `execute' /Users/jon/.rvm/rubies/ruby-2.2.1/lib/ruby/2.2.0/rake/task.rb:179:in `block in invoke_with_call_chain' /Users/jon/.rvm/rubies/ruby-2.2.1/lib/ruby/2.2.0/monitor.rb:211:in `mon_synchronize' /Users/jon/.rvm/rubies/ruby-2.2.1/lib/ruby/2.2.0/rake/task.rb:172:in `invoke_with_call_chain' /Users/jon/.rvm/rubies/ruby-2.2.1/lib/ruby/2.2.0/rake/task.rb:201:in `block in invoke_prerequisites' /Users/jon/.rvm/rubies/ruby-2.2.1/lib/ruby/2.2.0/rake/task.rb:199:in `each' /Users/jon/.rvm/rubies/ruby-2.2.1/lib/ruby/2.2.0/rake/task.rb:199:in `invoke_prerequisites' /Users/jon/.rvm/rubies/ruby-2.2.1/lib/ruby/2.2.0/rake/task.rb:178:in `block in invoke_with_call_chain' /Users/jon/.rvm/rubies/ruby-2.2.1/lib/ruby/2.2.0/monitor.rb:211:in `mon_synchronize' /Users/jon/.rvm/rubies/ruby-2.2.1/lib/ruby/2.2.0/rake/task.rb:172:in `invoke_with_call_chain' /Users/jon/.rvm/rubies/ruby-2.2.1/lib/ruby/2.2.0/rake/task.rb:165:in `invoke' /Users/jon/.rvm/rubies/ruby-2.2.1/lib/ruby/gems/2.2.0/gems/activerecord-4.2.1/lib/active_record/railties/databases.rake:139:in `block (2 levels) in ' /Users/jon/.rvm/rubies/ruby-2.2.1/lib/ruby/2.2.0/rake/task.rb:240:in `call' /Users/jon/.rvm/rubies/ruby-2.2.1/lib/ruby/2.2.0/rake/task.rb:240:in `block in execute' /Users/jon/.rvm/rubies/ruby-2.2.1/lib/ruby/2.2.0/rake/task.rb:235:in `each' /Users/jon/.rvm/rubies/ruby-2.2.1/lib/ruby/2.2.0/rake/task.rb:235:in `execute' /Users/jon/.rvm/rubies/ruby-2.2.1/lib/ruby/2.2.0/rake/task.rb:179:in `block in invoke_with_call_chain' /Users/jon/.rvm/rubies/ruby-2.2.1/lib/ruby/2.2.0/monitor.rb:211:in `mon_synchronize' /Users/jon/.rvm/rubies/ruby-2.2.1/lib/ruby/2.2.0/rake/task.rb:172:in `invoke_with_call_chain' /Users/jon/.rvm/rubies/ruby-2.2.1/lib/ruby/2.2.0/rake/task.rb:165:in `invoke' /Users/jon/.rvm/rubies/ruby-2.2.1/lib/ruby/2.2.0/rake/application.rb:150:in `invoke_task' /Users/jon/.rvm/rubies/ruby-2.2.1/lib/ruby/2.2.0/rake/application.rb:106:in `block (2 levels) in top_level' /Users/jon/.rvm/rubies/ruby-2.2.1/lib/ruby/2.2.0/rake/application.rb:106:in `each' /Users/jon/.rvm/rubies/ruby-2.2.1/lib/ruby/2.2.0/rake/application.rb:106:in `block in top_level' /Users/jon/.rvm/rubies/ruby-2.2.1/lib/ruby/2.2.0/rake/application.rb:115:in `run_with_threads' /Users/jon/.rvm/rubies/ruby-2.2.1/lib/ruby/2.2.0/rake/application.rb:100:in `top_level' /Users/jon/.rvm/rubies/ruby-2.2.1/lib/ruby/2.2.0/rake/application.rb:78:in `block in run' /Users/jon/.rvm/rubies/ruby-2.2.1/lib/ruby/2.2.0/rake/application.rb:176:in `standard_exception_handling' /Users/jon/.rvm/rubies/ruby-2.2.1/lib/ruby/2.2.0/rake/application.rb:75:in `run' /Users/jon/code/Bloccit/bin/rake:8:in `' /Users/jon/.rvm/rubies/ruby-2.2.1/lib/ruby/gems/2.2.0/gems/activesupport-4.2.1/lib/active_support/dependencies.rb:268:in `load' /Users/jon/.rvm/rubies/ruby-2.2.1/lib/ruby/gems/2.2.0/gems/activesupport-4.2.1/lib/active_support/dependencies.rb:268:in `block in load' /Users/jon/.rvm/rubies/ruby-2.2.1/lib/ruby/gems/2.2.0/gems/activesupport-4.2.1/lib/active_support/dependencies.rb:240:in `load_dependency' /Users/jon/.rvm/rubies/ruby-2.2.1/lib/ruby/gems/2.2.0/gems/activesupport-4.2.1/lib/active_support/dependencies.rb:268:in `load' /Users/jon/.rvm/rubies/ruby-2.2.1/lib/ruby/site_ruby/2.2.0/rubygems/core_ext/kernel_require.rb:54:in `require' /Users/jon/.rvm/rubies/ruby-2.2.1/lib/ruby/site_ruby/2.2.0/rubygems/core_ext/kernel_require.rb:54:in `require' -e:1:in `' Tasks: TOP => db:setup => db:seed 

我在这里难过。 我想通过删除旧表并运行新的生成命令+迁移一切都将按顺序进行。 显然事实并非如此。

我在这做错了什么?

编辑包括我的种子的第45行.rb

 Comment.create!( 

您的迁移错误 – 而不是在添加user_idcomments中添加user_id

哎呀。 它可能发生在我们最好的人身上。

首先让我们创建一个迁移来清除这个错误:

 class RemoveCommedFromUsers < ActiveRecord::Migration def change remove_column :users, :commed # will also remove the index end end 

当然,如果尚未部署应用程序,您可以删除有问题的迁移并运行rake db:reset

因此,让我们创建正确的迁移

 rails g migration AddUserToComments user:belongs_to 

这会生成以下迁移:

 class AddUserToComments < ActiveRecord::Migration def change add_reference :comments, :user, index: true end end 

add_reference在一次扫描中创建索引和外键。