首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >使用关系查询的Rails

使用关系查询的Rails
EN

Stack Overflow用户
提问于 2016-04-29 17:08:17
回答 1查看 2.4K关注 0票数 2

我试图使用where查询与关系。

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

这是模型

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
User
  has_many :projects
  has_many :reasons, through: :projects

Project
  belongs_to :user
  has_many :reasons

Reasons
  belongs_to :project

这是不起作用的密码

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
  # 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,这是正确的。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
reasons = reasons.joins(:project).where("projects.updated_at > ?", Time.at(updated_at.to_i))
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-04-29 17:18:46

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
reasons = reasons.joins(:project).where("projects.updated_at > ?", Time.at(updated_at.to_i))

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

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

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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对象的ActiveRecord关联。

以上最后一步意味着您可以安全地完成以下操作:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
reasons.first.project

并且不会启动任何查询来获取第一个原因的项目。这就是为什么使用includes来解决N+1查询的原因。但是,请注意,SQL中没有JOIN子句--它们是单独的SQL。因此,在使用includes时不能添加SQL约束。

这就是joins进来的原因。它只是将表连接起来,这样就可以在已连接的表上添加where约束。但是,它并没有为您预先填充关联。实际上,Reason.joins(:project)永远不会实例化Project ActiveRecord对象。

如果要同时执行joinsincludes,可以使用第三个方法eager_load。您可以阅读更多关于差异的这里

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36949647

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文