我无法相信在经过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
似乎同样缓慢。
这个常见问题是否有灵丹妙药?
答案 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的::关系