繁体   English   中英

Rails 3 has_many至has_one

[英]rails 3 has_many through has_one

假设您具有以下模型:

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

令人惊讶的是,当我调用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

上面的查询忽略了Category#current_heat的has_one性质。 我本来期望更像:

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

仅当您使用Category.first.current_heat.scores从根显式遍历has_one关联时,才会生成该代码。

就像ActiveRecord默默地将我的has_one视为has_many一样。 有人可以向我解释这种行为吗? 是否有优雅的解决方法或“正确的方法”来做到这一点?

也许您可以删除

has_many :scores, :through => :current_heat

而是通过has_one委托:scores:

delegate :scores, :to => :current_heat

这将保留您所需的访问方法Category.first.scores。

has_one确实不存在以这种方式来照料数据库。 如果有多个记录与foreign_key匹配,它不会抛出错误,它只会选择第一个。 假定您没有错误地添加额外的记录,这些记录会自行破坏has_one关系。

总之,只要类别中仅附加一条记录,它生成的sql就可以了。 如果您以某种方式添加了额外的记录(由于它是has_one而不应该存在),那么它将不起作用,但是告诉您这已经发生不是activerecord的工作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM