订单有很多LineItems。 LineItems有名字,比如“car”。我想查找所有包含名称与某个模式匹配的订单项的订单。
我知道我可以做LineItem.where('name ~* :pat', pat: 'car')
,例如。
我也知道我能做到
Order.where.not(state: "cancelled")
.includes(:line_items)
.where(line_items: { name: "car" })
我不确定组合这两个查询的语法。我想它就像是,
Orders.where.not(state: 'cancelled')
.includes(:line_items)
.where(line_items: ['name ~* :pat', pat: 'car'])
这对google来说很棘手,所以我想我会把它给你。
注意:上次我有关于Rails activerecord的问题时,解决方案的一部分是检查SQL。但是,在这种情况下,使用includes方法会导致一些疯狂的可怕SQL。试试这样的事情,
Order.includes(:line_items).where(line_item: { name: "car"}).to_sql
在你的rails控制台中玩得很开心!
注意:我明确需要帮助解决这个问题的标题。
答案 0 :(得分:0)
如rails guide中所述,
使用这样的地方只有在你传递哈希时才会有效。 对于SQL片段,您需要使用引用强制连接表:
Post.includes(:comments).where("comments.visible = true").references(:comments)
所以在我的情况下,查询将是:
Orders.where.not(state: 'cancelled')
.includes(:line_items)
.where('line_items.name ~* ?', 'car').references(:line_items)
这将返回包含名称与给定正则表达式匹配的订单项的所有订单,并预先加载这些订单项。如果您不想预加载订单项,请使用joins
代替includes
。
如果您想为每个订单预加载所有订单项,我不知道您会怎么做,无论条件如何(但希望我不需要^ o ^ //)
编辑:this article详细说明了究竟发生了什么,并回答了我的第二个问题。要预加载您必须使用的所有订单项... preload
ha!
Orders.where.not(state: 'cancelled')
.joins(:line_items) # note the joins
.where('line_items.name ~* ?', 'car').references(:line_items)
.preload(:line_items)
如果你在这里再次使用.includes
,你将会失望。它必须是preload
。此查询获取我想要的订单,并预加载所有订单项,无论它们是否与用于过滤订单的正则表达式匹配。