gpt4 book ai didi

ruby-on-rails - Rails 5 ActiveRecord 可选包含嵌套关联的属性的位置

转载 作者:行者123 更新时间:2023-12-04 08:38:03 24 4
gpt4 key购买 nike

假设这个简化的模式:users has_many discount_codesdiscount_codes has_many orders我要全部抢users ,如果他们碰巧有任何 orders ,仅包括在两个日期之间创建的订单。 但是如果他们没有订单,或者只有这两个日期之外的订单,仍然返回用户并且永远不排除任何用户。
我现在在做什么:

users = User.all.includes(discount_codes: :orders)

users = users.where("orders.created_at BETWEEN ? AND ?", date1, date2).
or(users.where(orders: { id: nil })
我相信我的 OR 子句允许我保留没有任何订单的用户,但是如果我的用户只有 date1 和 date2 之外的订单,那么我的查询将排除该用户。
对于它的值(value),我想使用这个订单 where在这里特别是条款,以便我可以在稍后确定每个用户的订单时避免 n + 1 问题。
提前致谢!

最佳答案

尝试控制作为用户 where 子句一部分加载的订单是没有意义的。如果您要控制它必须是包含的一部分(我认为这意味着它必须是关联的一部分)。
尽管从技术上讲,在某些情况下它可以将它们合并为一个查询,但 activerecord 会将其作为两个查询来执行。
第一个查询将在您遍历用户时执行,并将使用该 where 子句来限制找到的用户。
然后它将根据包含语句在后台运行第二个查询。这将只是一个查询,用于获取与上一个查询找到的用户相关联的所有订单。因此,控制通过用户的 where 子句找到的订单的唯一方法是从结果集中省略用户。
如果我是你,我会在 User 模型中为你正在寻找的东西创建一个实例方法,而不是使用 where 使用 select 块:

def orders_in_timespan(start, end)
orders.select{ |o| o.between?(start, end) }
end
由于 ActiveRecord 将根据实例缓存从包含中找到的订单的方式,那么如果您从用户查询中的包含开始,那么我相信这不会导致 n 查询。
就像是: render json: User.includes(:orders), methods: :orders_in_timespan当然,确认查询次数的最简单方法是查看日志。我相信这种方法应该有两个查询,而不管呈现的用户数量有多少(问题中的代码很可能也是如此)。
另外,我不确定您对 sql 有多熟悉,但您可以在诸如用户变量之类的事物的末尾调用 .to_sql 以查看将生成的 sql,这可能有助于阐明什么之间的差异你得到了什么,你正在寻找什么。

关于ruby-on-rails - Rails 5 ActiveRecord 可选包含嵌套关联的属性的位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64703305/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com