gpt4 book ai didi

sql - Ruby on Rails 查询关系

转载 作者:太空宇宙 更新时间:2023-11-03 18:09:39 26 4
gpt4 key购买 nike

我正在尝试对关系使用 where 查询。

在这种情况下,如何使用关系查询?

这是模型

User
has_many :projects
has_many :reasons, through: :projects

Project
belongs_to :user
has_many :reasons

Reasons
belongs_to :project

这是行不通的代码

  # GET /reasons
def index
reasons = current_user.reasons
updated_at = params[:updated_at]

# Filter with updated_at for reloading from mobile app
if updated_at.present?



# This one doesn't work!!!!!!!!!!!!
reasons = reasons.includes(:projects).where("updated_at > ?", Time.at(updated_at.to_i))



# Get all non deleted objects when logging in from mobile app
else
reasons = reasons.where(deleted: false)
end

render json: reasons
end

---更新---

感谢@AmitA,这是正确的。

reasons = reasons.joins(:project).where("projects.updated_at > ?", Time.at(updated_at.to_i))

最佳答案

如果要查询项目有一些约束的所有原因,需要使用joins而不是includes:

reasons = reasons.joins(:project).where("projects.updated_at > ?", Time.at(updated_at.to_i))

请注意,当 includesjoins 都收到一个符号时,它们会查找与该精确名称的 association。这就是为什么您实际上不能执行 includes(:projects),而必须执行 includes(:project)joins(:project) 的原因。

另请注意,where 指定的连接表约束必须引用表名,而不是关联名。这就是为什么我使用 projects.updated_at(复数形式)而不是其他任何东西。换句话说,当调用 where 方法时,您处于“SQL 域”中。

includesjoins 是有区别的。 includes 运行一个单独的查询来加载依赖项,然后将它们填充到获取的事件记录对象中。所以:

reasons = Reason.where('id IN (1, 2, 3)').includes(:project)

将执行以下操作:

  1. 运行查询 SELECT * FROM reasons WHERE id IN (1,2,3),并为每条记录构建 ActiveRecord 对象 Reason
  2. 查看获取的每个原因并提取其 project_id。假设这些是 11、12、13。然后运行查询 SELECT * FROM projects WHERE id IN (11,12,13)​​ 并为每条记录构造 ActiveRecord 对象 Project
  3. 预填充第 1 步中获取的每个 Reason ActiveRecord 对象的 project 关联。

上面的最后一步意味着您可以安全地执行以下操作:

reasons.first.project

并且不会发起查询来获取第一个原因的项目。这就是为什么要用includes来解决N+1查询的原因。但是,请注意 SQL 中没有出现 JOIN 子句——它们是单独的 SQL。所以当你使用includes时你不能添加SQL约束。

这就是 joins 的用武之地。它只是连接表,以便您可以在连接的表上添加 where 约束。但是,它不会为您预先填充关联。事实上,Reason.joins(:project) 永远不会实例化 Project ActiveRecord 对象。

如果您想同时执行joinsincludes,您可以使用第三种方法eager_load。您可以阅读更多关于差异的信息 here .

关于sql - Ruby on Rails 查询关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36949647/

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