mysql - 关联后跟命名范围会产生重复的 SQL 查询

标签 mysql ruby-on-rails associations named-scope

我在工作中遇到了这个奇怪的问题,因此我创建了一个最小的应用程序来突出显示该问题。我有两个具有简单关联的模型:

class Parent < ActiveRecord::Base
  has_many :children
end

class Child < ActiveRecord::Base
  belongs_to :parent
  named_scope :only_adults, :conditions => "adult is true"
end

现在当我这样做的时候

 p = Parent.first
 p.children.only_adults.all()

我希望 Rails 生成包含所有条件的单个 SQL 查询。但是,这是我在日志中看到的内容:

Child Load (0.5ms)   SELECT * FROM "children" WHERE ("children".parent_id = 1) 
Child Load (0.3ms)   SELECT * FROM "children" WHERE ("children".parent_id = 1) AND ((adult is true) AND ("children".parent_id = 1)) 

第一个查询基本上是无用的,并且在大型集合的情况下可能非常耗时。

有人知道为什么 Rails 会这样吗?

请注意,而不是这样做

p.children.only_adults.all()

我愿意

Child.by_parent(p.id).only_adults.all()

其中 by_parent 是命名范围,那么我只得到一个查询。

另请注意 Parent_id 条件的重复。这没什么大不了的。

感谢您的反馈。

最佳答案

原因与 Rails 2.3.x(而不是 Rails 3.0.x)中执行查询的方式有关。在 Rails 2 中,调用 p.children 将自动执行查询,无论您附加到查询其余部分的命名范围如何。解决这个问题的唯一方法是结合使用named_scopes,就像您在“Child.by_parent(p.id).only_adults.all()”中所做的那样,因为命名范围保留了推迟查询的行为。在 Rails 3 中,查询会一直构建,直到找到执行关键字(count、all、first、last),因此可以在单个查询中执行以下操作:

class Child < ActiveRecord::Base
  belongs_to :parent
  scope :only_adults, where(adult: true)
end

Parent.first.children.only_adults.all()

# SELECT * FROM "children" WHERE ("children".parent_id = 1) AND (adult is true)

关于mysql - 关联后跟命名范围会产生重复的 SQL 查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4960470/

相关文章:

associations - UML 角色名称是否应该反射(reflect)在类属性中?

mysql - 在 InnoDB 表列中搜索字符串

ruby-on-rails - rails : how to not render view by default?

ruby-on-rails - 如何使用 seeds.rb 以外的文件播种

symfony - 当一个实体不受 Doctrine 管理时的关联映射

php - CakePHP 关联错误 : Call to a member function find() on a non-object

php - MySQL (# of Products in Category) COUNT() with/L​​EFT JOIN and ON 2 Tables

php - 为什么我的电子邮件和数据库会得到 2 个不同的值?

mysql - 我有两个名为 created_at 和 updated_at(timestamps) 的字段,我想在我的 where 子句中的这些日期之间进行搜索

ruby-on-rails - 安装 ruby​​ ruby​​-1.9.3-p551 时出错