Rails:找到关系的关系

时间:2016-01-13 07:34:07

标签: ruby-on-rails ruby

我无法相信在经过5年的Rails编程之后,我还没有找到解决这个常见问题的好方法。此外,我假设这个特定问题有100个答案,但我不知道定义(关系?关联等等)以便很好地搜索它。所以我们走了:

我有两个模型:类别和产品以及一个将它们捆绑在一起的CategoryProductRelation模型。

类别模型:

has_many :category_product_relations
has_many :products, :through => :category_product_relations

CategoryProductRelation模型:

has_many :products
has_many :categories

类别通常有1000种产品。

问题

我经常需要进行搜索,例如"食品类别中的所有产品"即分类:'水果' (1),'谷物' (2),'肉类'(3)。

基本上,我喜欢做的事情就像Category.where(:id => [1,2,3]).products,显然不起作用。

我的(慢)解决方案

我经常做的是这样的事情:

products = Product.where(:id => CategoryProductRelation.where(:category_id => [1,2,3]).pluck(:product_id))

哪个有效,大多数也很好。但是,如果产品数量很大导致400ms查询,则速度非常慢!

更聪明的方式,对吧?这感觉就像Rails 101,但我无法用简单的方式解决它,并且快速

最后,通过类别迭代:

Category.where(:id => [1,2,3]).each do |category|
category.products 
#...and so on
end

似乎同样缓慢。

这个常见问题是否有灵丹妙药?

4 个答案:

答案 0 :(得分:1)

includes应该有所帮助。没有测试,但是像:

Category.includes(:products).where(id: [1, 2, 3]).flat_map(&:products)

答案 1 :(得分:1)

我不确定这是否适用于您的情况。我使用mongoid所以我做这样的事情。

Product.where(:category_id.in => [1,2,3])

这给了我所有产品的ID为1,2,3的类别。

对于产品型号

belongs_to :category

对于类别模型

has_many :products

我希望你有个主意。

对于两个查询,您可以执行以下操作。

category_product_relations_ids = CategoryProductRelation.where(:category_ids => [1,2,3]).pluck(:id)
Product.where(:category_product_relation_id => category_product_relations_ids)

答案 2 :(得分:1)

神奇的词是数据库连接。 要使用它,你需要在相反的方向思考一点。 您要求在连接桌上提供具有条件的产品。

http://guides.rubyonrails.org/active_record_querying.html#joining-tables

具体地寻找:" 12.3。 12.3在连接表上指定条件"

所以它就像

function getDateOfISOWeek(w, y) {
    var simple = new Date(y, 0, 1 + (w - 1) * 7);
    var dow = simple.getDay();
    var ISOweekStart = simple;
    if (dow <= 5)
        ISOweekStart.setDate(simple.getDate() - simple.getDay() + 1);
    else
        ISOweekStart.setDate(simple.getDate() + 8 - simple.getDay());
    return ISOweekStart;
}

答案 3 :(得分:1)

merge怎么样?

Product.joins(:categories).merge(Category.where(:id => [1,2,3])).pluck(:id)

http://apidock.com/rails/ActiveRecord/SpawnMethods/merge

  

合并其他条件,如果是其他条件   ActiveRecord的::关系