Sql 复杂查询,是否同时使用:includes和:join?

Sql 复杂查询,是否同时使用:includes和:join?,sql,ruby-on-rails,Sql,Ruby On Rails,(使用Rails 3.1.3) 我有一个管理产品的应用程序。我从几家经销商那里进口产品,他们对产品的分类都不一样。正因为如此,我的经销商类别映射到我自己的子类别 类别 子类别(属于类别) 经销商类别(属于子类别) 产品(属于经销商类别) 您可以在此处看到模型以及如何定义关系: 在我的网站上,我想简单地显示类别及其子类别 如果用户只过滤“女性”产品,我还想过滤类别和子类别,以便只显示具有“女性”产品的类别和子类别。性别存储在产品中 那么,我该怎么做呢 我尝试创建如下查询: (我认为)它过滤了正确

(使用Rails 3.1.3)

我有一个管理产品的应用程序。我从几家经销商那里进口产品,他们对产品的分类都不一样。正因为如此,我的经销商类别映射到我自己的子类别

类别

子类别(属于类别)

经销商类别(属于子类别)

产品(属于经销商类别)

您可以在此处看到模型以及如何定义关系:

在我的网站上,我想简单地显示类别及其子类别

如果用户只过滤“女性”产品,我还想过滤类别和子类别,以便只显示具有“女性”产品的类别和子类别。性别存储在产品中

那么,我该怎么做呢

我尝试创建如下查询: (我认为)它过滤了正确的类别。然而,当我做一些类似的事情时:

@menu_categories.each do |c|
    c.subcategories.each do |sc|
        # do something...
    end
end
它仍然查询所有子类别是否有女性产品。因此,我在RubyonRails谷歌小组得到一个建议,使用.includes()急切地加载:子类别。比如说:

Category.includes(:subcategories)
        .joins("INNER JOIN resellercategories AS r ON subcategories.id = r.subcategory_id")
        .joins("INNER JOIN products AS p ON r.id = p.resellercategory_id")
        .group("categories.id")
        .order("categories.name ASC")
        .where("p.gender = 'unisex' OR p.gender = 'female'")
        .where("subcategories.id > 0") # Dummy to trigger eager loading
但是,当混合使用.includes()和.joins()时,includes似乎无法加载任何内容。因此抛出以下错误:

ActiveRecord::StatementInvalid: SQLite3::SQLException: no such column: subcategories.id:
SELECT "categories".* FROM "categories" 
INNER JOIN resellercategories AS r ON subcategories.id = r.subcategory_id 
INNER JOIN products AS p ON r.id = p.resellercategory_id 
WHERE (p.gender = 'unisex' OR p.gender = 'female') 
GROUP BY categories.id 
ORDER BY categories.name ASC
这是预期的行为吗?是虫子吗? 我是想用正确的方法还是有更好的方法

非常感谢您的帮助

(关于RoR谷歌集团的讨论:)

解决方案: 好的,解决方案是使用eager_load()而不是includes()。我还必须删除组() 这似乎对我有用:

 Category.eager_load(:subcategories)
         .joins("INNER JOIN resellercategories AS r ON subcategories.id = r.subcategory_id")
         .joins("INNER JOIN products AS p ON r.id = p.resellercategory_id")
         .order("categories.name ASC")
         .where("p.gender = 'unisex' OR p.gender = 'female'")

Rails并不总是使用连接来实现包含。您也可以通过执行
eager\u load
而不是
includes
来强制加载

这条AR链看起来干净多了

Category.joins({:subcategories => 
               {:resellercategories =>
                :products}})
         .includes(:subcategories)
         .where('products.gender = unisex OR
                 products.gender = ?', gender)
但我不认为它能解决您获取所有
子类别的原始问题。要解决这个问题,实际上必须查询关联

@menu_categories.each do |c|
    c.subcategories.joins({:resellercategories =>
                           :products}})
                   .where('products.gender = unisex OR
                           products.gender = ?', gender)
                   .each do |sc|
        # do something...
    end
end

自定义的
.joins
优先或类似的愚蠢行为。我看看能不能想出更好的办法。谢谢!急切的加载()似乎起到了作用。我还必须删除组()。将用正确的信息更新我的原始帖子。