【问题标题】:Ruby on Rails Active Record query joining two tables and query based on conditionRuby on Rails Active Record 查询连接两个表并根据条件查询
【发布时间】:2019-11-10 04:21:22
【问题描述】:

我有两个表:事务和属性。

我有一个条件要满足,即不需要加入表。

在我的交易查询中:

  • sales_date 在某个月份的行
  • sold_or_leased 被“租用”的行

我的下一个条件需要将属性加入交易,以便我可以:

  • transactions.sales_date 在某个月份的行
  • transactions.sold_or_leased 为空 AND 的行
  • properties.for_sale 为假且properties.for_lease 为真的行

基本上,在名为sold_or_leased 的事务中添加了一个新列,其中很多为空。我需要一个额外的查询来覆盖null 列。

    #test variables for month
    date = "2019-11-01"
    month = Date.parse date

    # below satisfies my first part
    @testobj = Transaction.where(sold_or_leased: "leased")
      .where("sales_date >= ? AND sales_date < ?", month.beginning_of_month, month.end_of_month).count

但现在我需要扩展此查询以包含属性并测试属性列

我不知道从这里去哪里:

    @testobj = Transaction.joins(:property)
      .where(sold_or_leased: "leased")
      .where("sales_date >= ? AND sales_date < ?", month.beginning_of_month, month.end_of_month)
      .or(
        Transaction.where(sold_or_lease: nil)
      ).count

另外,当我添加一个连接然后添加一个 or 子句时,我收到一个错误 Relation passed to #or must be structurally compatible. Incompatible values: [:joins]

我将分享相关型号信息:

交易模型:

class Transaction < ApplicationRecord
  belongs_to :user
  belongs_to :property
end 

属性模型:

class Property < ApplicationRecord
  has_one :property_transaction, class_name: 'Transaction', dependent: :destroy
end

在 Sebastian 的帮助下,我得到了以下信息(仍然会产生结构性错误消息):

Transaction.joins(:property)
    .where(sales_date: month.all_month,
           sold_or_leased: nil,
           properties: { for_sale: false, for_lease: true })
    .or(
      Transaction.joins(:property)
      .where(sold_or_leased: "leased")
      .where("sales_date >= ? AND sales_date < ?", month.beginning_of_month, month.end_of_month)
    )

【问题讨论】:

  • 你的模型看起来怎么样?
  • 我添加了一个模型外观示例。我剪掉了不相关的行
  • 我测试了你的查询 Transaction.joins(:property).where(sales_date: month.all_month, sold_or_leased: nil, properties: { for_sale: false, for_lease: true }).or(Transaction.joins(:property).where(sold_or_leased: "leased").where("sales_date &gt;= ? AND sales_date &lt; ?", month.beginning_of_month, month.end_of_month)) 并且没有任何问题 1/2。
  • 不错!慢慢来,检查一切是否按预期工作;)
  • @SebastianPalma 确认正在返回正确的数据:)。你是救生员!再次感谢!

标签: ruby-on-rails activerecord


【解决方案1】:

理论上,您应该能够在连接后访问properties 表列。

查看您当前的代码以及您可以尝试的内容:

Transaction
  .joins(:property)
  .where(sales_date: month.all_month)
  .where(
    "(sold_or_leased IS NULL AND properties.for_sale = false AND properties.for_lease = true) OR
     (sold_or_leased = 'leased')"
  )

如果您无法使用ActiveRecord::QueryMethods#or,您始终可以在where 的字符串参数中使用SQL OR 运算符。

通知month.all_month 生成相应月份的整个日期范围,当与where 一起使用时,将转换为该月的第一天和最后一天:

SELECT ... WHERE "transactions"."sales_date" BETWEEN $1 AND $2 AND ... [["sales_date", "2019-11-01"], ["sales_date", "2019-11-30"]]

比month.beginning_of_month 和month.end_of_month 变体短。

【讨论】:

  • 谢谢塞巴斯蒂安!您的第一个查询帮助我获得了这些行,但是,我仍然无法组合这两个查询。在您对“结构兼容”进行编辑后,尽管我相信我的格式正确,但我仍然会收到错误消息。我会用我所拥有的来编辑我的问题
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多