我是Rails的初学者(刚完成Hartl的教程),而且我遇到了一些类型的关联,这些关联似乎比我更复杂一些到目前为止已经暴露。我一直在浏览谷歌和stackoverflow为我的问题的解决方案,但虽然我发现很多相关的答案,我仍然无法弄清楚如何解决我的问题。与Rails 3.2上的自定义表名的多对多关系
基本上我试图做的是实现以下关系:
什么,我想出了是研究一下后:
模式
# models/user.rb
class User < ActiveRecord::Base
attr_accessible :first_name, :last_name, :email …
has_many :speak, :class_name => "Speaks"
has_many :speaks, :through => :speak, :source => :language
has_many :want_to_learn, :class_name => "WantsToLearn"
has_many :wants_to_learn, :through => :want_to_learn, :source => :language
…
end
# models/language.rb
class Language < ActiveRecord::Base
attr_accessible :iso_639_1_code, :name_en, :name_fr, :name_pt
has_many :speak, :class_name => "Speaks"
has_many :users_who_speak, :through => :speak, :source => :user
has_many :want_to_learn, :class_name => "WantsToLearn"
has_many :users_who_want_to_learn, :through => :wants_to_learn, :source => :user
end
# models/speaks.rb
class Speaks < ActiveRecord::Base
set_table_name 'speak'
attr_accessible :level, :language
references :user
references :language
end
# models/wants_to_learn.rb
class WantsToLearn < ActiveRecord::Base
set_table_name 'want_to_learn'
attr_accessible :language
references :user
references :language
end
迁移
# db/migrate/20130210153328_create_speak.rb
class CreateSpeak < ActiveRecord::Migration
def change
create_table :speak do |t|
t.references :user
t.references :language
t.integer :level
t.timestamps
end
end
add_index :speak, :user
add_index :speak, :language
end
# db/migrate/20130210153342_create_want_to_learn.rb
class CreateWantToLearn < ActiveRecord::Migration
def change
create_table :want_to_learn do |t|
t.references :user
t.references :language
t.timestamps
end
end
add_index :want_to_learn, :user
add_index :want_to_learn, :language
end
当我做到这一点,尝试运行rake:db migrate
,我得到以下错误:
-- add_index(:speak, :user)
rake aborted!
An error has occurred, this and all later migrations canceled:
PG::Error: ERROR: relation "speak" does not exist
: CREATE INDEX "index_speak_on_user" ON "speak" ("user")
...
如果我注释掉与add_index
迁移成功运行的线路,但我不能创建一个来自用户的“说话”关系。例如,如果我运行:
> john = User.new(first_name: "John", last_name: "Doe", email: "[email protected]"...)
> john.speaks.create!(level: '6', language: '139')
我得到:
NoMethodError: undefined method `references' for #<Class:0x007ff14c1771a0>
我试图取代所有的“引用”与“belongs_to的”等几件事情,其中有许多我不知道甚至记住,但无济于事。这在我的脑海中引起了一些疑问,如:
•“引用”与“belongs_to”是否真的相同?即使在模型的情况下?我已经看到“参考”被用于迁移,但从来没有模型。
•我正确使用“class_name”吗?我对此确实没有信心。这正是我读过的所有东西之后最有意义的东西,但我还没有看到任何像这样的关联中定制的例子。
•添加这些索引有什么问题?
和好了,我不知道这里的礼仪,但我的最后一个问题是:
如何做到这一切正常?
预先感谢您!
------ 编辑 ------
我替换的关键字 “引用” 与 “belongs_to的” 无处不在。有关索引的迁移错误完全相同。当我评论索引创建线路,运行迁移,创建一个用户,然后尝试命令
> john.speaks.create!(level: 6, language: 139)
的错误是:
ActiveModel::MassAssignmentSecurity::Error:
Can't mass-assign protected attributes: level, language
尽管线attr_accessible :level, :language
的。
嘿,谢谢你的快速回答。我将所有出现的“引用”都改为“belongs_to”。我编辑了添加此更改结果的问题。 – Ariel 2013-02-24 13:05:11