我正在尝试实施“评论”功能,作为我正在建设的项目的一部分。
在本课程的早期,我们创建了一个评论表,并让Faker gem生成虚假评论。
我的说明如下:
注释必须与用户关联,因此将user_id外键添加到comments表中。请记住也要为其添加索引;
更新用户模型,以便您可以调用user.comments和Comment模型,以便调用comment.user;
修改seeds.rb文件以在运行db:reset;
时创建有效注释
最初我尝试运行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 `<main>'
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 `<main>'
SQLite3::SQLException: table "comments" already exists
/Users/jon/code/bloccit/db/migrate/20150508143445_create_comments.rb:3:in `change'
-e:1:in `<main>'
Tasks: TOP => db:migrate
(See full trace by running task with --trace)
所以我发现我需要从课程开始时删除旧表。我在控制台中这样做了。
ActiveRecord::Base.connection.execute("drop table comments")
似乎有效。然后我就可以在终端运行这些了。</ p>
▶ 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
在我的 seeds.rb 中,我更改了
# 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 <top (required)>'
/Users/jon/code/Bloccit/db/seeds.rb:44:in `times'
/Users/jon/code/Bloccit/db/seeds.rb:44:in `<top (required)>'
-e:1:in `<main>'
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 <top (required)>'
/Users/jon/code/Bloccit/db/seeds.rb:44:in `times'
/Users/jon/code/Bloccit/db/seeds.rb:44:in `<top (required)>'
/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 <top (required)>'
/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 <top (required)>'
/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 `<top (required)>'
/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 `<main>'
Tasks: TOP => db:setup => db:seed
我在这里难过。我想通过删除旧表并运行新的生成命令+迁移一切都将按顺序进行。显然事实并非如此。
我在这里做错了什么?
编辑以包含我的seeds.rb第45行
Comment.create!(
答案 0 :(得分:5)
您的迁移错误 - 而不是向user_id
添加comments
,而是添加users.commed
。
糟糕。它可能发生在我们最好的人身上。
首先,让我们创建一个迁移来清除这个错误:
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
在一次扫描中创建索引和外键。