[英]rails 3 has_many through has_one
Suppose you have the following models: 假设您具有以下模型:
class Category < ActiveRecord::Base
has_one :current_heat, class_name: 'Heat'
has_many :scores, :through => :current_heat
end
class Heat < ActiveRecord::Base
belongs_to :category
has_many :scores
end
class Score < ActiveRecord::Base
belongs_to :heat
end
Surprisingly, when I invoke Category.first.scores
ActiveRecord produces the following queries: 令人惊讶的是,当我调用
Category.first.scores
ActiveRecord会产生以下查询:
SELECT `categories`.* FROM `categories` LIMIT 1
SELECT * FROM `scores` INNER JOIN `heats` ON `scores`.`heat_id` = `heats`.`id` WHERE `heats`.`category_id` = 1
The above query ignores the has_one nature of Category#current_heat
. 上面的查询忽略了
Category#current_heat
的has_one性质。 I would have expected something more like: 我本来期望更像:
SELECT `categories`.* FROM `categories` LIMIT 1
SELECT `heats`.* FROM `heats` WHERE `heats`.`category_id` = 1 LIMIT 1
SELECT * FROM `scores` WHERE `scores`.`heat_id` = 6
which is produced only when you explicitly traverse the has_one association from the root with Category.first.current_heat.scores
. 仅当您使用
Category.first.current_heat.scores
从根显式遍历has_one关联时,才会生成该代码。
It's as if ActiveRecord is silently treating my has_one as a has_many. 就像ActiveRecord默默地将我的has_one视为has_many一样。 Can someone explain this behavior to me?
有人可以向我解释这种行为吗? Is there an elegant workaround or a "right way" to do it?
是否有优雅的解决方法或“正确的方法”来做到这一点?
Maybe you could remove the 也许您可以删除
has_many :scores, :through => :current_heat
and instead just delegate :scores through the has_one: 而是通过has_one委托:scores:
delegate :scores, :to => :current_heat
that would preserve your desired access method Category.first.scores. 这将保留您所需的访问方法Category.first.scores。
has_one
doesn't really exist to babysit your database in this fashion. has_one
确实不存在以这种方式来照料数据库。 It won't throw errors if there is more than one record that matches the foreign_key, it will just choose the first one. 如果有多个记录与foreign_key匹配,它不会抛出错误,它只会选择第一个。 It assumes you haven't errantly added extra records which would break the
has_one
relation on your own. 假定您没有错误地添加额外的记录,这些记录会自行破坏
has_one
关系。
In conclusion, the sql that it generates is fine as long as there is only one record attached to the Category. 总之,只要类别中仅附加一条记录,它生成的sql就可以了。 If somehow you've added extra records which shouldn't exist since it is a
has_one
, then it won't work, but it's not the job of activerecord to tell you that this has happened. 如果您以某种方式添加了额外的记录(由于它是
has_one
而不应该存在),那么它将不起作用,但是告诉您这已经发生不是activerecord的工作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.