sql - Ruby on Rails where 关系查询

标签 sql ruby-on-rails ruby activerecord

我正在尝试将 where 查询与关系一起使用。

在这种情况下如何使用带有关系的 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 都收到符号时,它们会查找与该精确名称的关联。这就是为什么您实际上不能执行 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 * FROMprojects 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 where 关系查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36949647/

相关文章:

sql - 重复时间(1 AM-1 :59:59 AM) on first Sunday of November - Daylight Savings ending day - Oracle

mysql - SQL查询GROUP BY,返回符合LEAST、COALESCE条件的分组

ruby-on-rails - 使用 Mongoid (MongoDB)、Redis、Resque、Capistrano 等部署 Ruby on Rails 应用程序

ruby - 如何正确使用 mongoid-rspec gem?

ruby-on-rails - 在 ruby​​ 中添加 span 标签链接?

mysql - 如何优化这个 MySQL 查询?

asp.net - 实现礼品卡

ruby-on-rails - FactoryGirl — 工厂未注册

ruby-on-rails - 如何在不验证的情况下更新属性

ruby-on-rails - Controller Action 中未定义的方法新