【问题标题】:ActiveRecord - Querying association with multiple condition pairsActiveRecord - 查询与多个条件对的关联
【发布时间】:2017-07-16 07:11:48
【问题描述】:

这里有一些关于小型数据库架构的上下文

Order
  -> id
LineItem
  -> id
  -> order_id
Transaction
  -> id
  -> transaction_type
  -> successful
  -> line_item_id

基本上,我们正在尝试做的是获取具有多个交易的所有订单,匹配交易的特定条件对

这是一个非常基本的表模式,可以用作示例:

Order (orders)
+----+
| id | 
|----|
|  1 |
|  2 | <--
|  3 |

Line Items (line_items)
+---------------+
| id | order_id |
|----|----------|
| 1  | 1        |
| 2  | 2        | <--
| 3  | 3        |

Transactions (transactions)
+---------------------------------------------------+
| id | transaction_type | successful | line_item_id |
|----|------------------|------------|--------------|
| 1  | 2                | 1          | 1            |
| 2  | 2                | 0          | 2            | <--
| 3  | 1                | 1          | 1            |
| 4  | 3                | 1          | 2            | <--
| 5  | 1                | 1          | 3            |
| 6  | 3                | 1          | 3            |

我用箭头突出了我们将关注的记录。

Order 类更多地放在上下文中:

class Order < ActiveRecord::Base
    has_many :line_items
    has_many :transactions, through: :line_items
end

正如我所说,我们希望通过transactions 上的特定约束(对)获取所有订单。

所以如果我们有(At least ONE transaction with "transaction_type" = 2 AND "successful = 0"), AND (At least ONE transaction with "transaction_type" = 3 AND "successful" = 1),我们只想选择一个order

这个不能OR。仅当遵守两个约束对时才应选择顺序。

(例如:我只想要订单,其订单项中只有一个类型为 2 的交易并且不成功)。 [这应该只给我订单的订单项具有单一类型的交易,尽管它可以有任何其他类型的交易]

过去 10 小时我一直在寻找如何实现这一目标,但无济于事,因此我向您寻求答案。 如果您好奇:我们使用 postgres

我什至不知道从哪里开始查询,更不用说 ActiveRecord 语法了。

问题的好例子: https://github.com/dsounded/ransack_example/blob/master/app/services/finder.rb#L7 这样做的问题是无法对结果进行排序或分页。

【问题讨论】:

    标签: ruby-on-rails postgresql ruby-on-rails-4 activerecord


    【解决方案1】:

    你可以尝试自己加入交易

    Transactions.joins("INNER JOIN transactions as x ON x.line_item_id=transactions.line_item_id").where("transactions.transaction_type=2 AND transactions.successful=0").where("x.transaction_type=3 AND x.successful=1").includes(:order)
    

    【讨论】:

    • 这样的查询结果是nil:SELECT COUNT(*) FROM "transactions" INNER JOIN transactions as x ON x.line_item_id=transactions.line_item_id WHERE (transactions.transaction_type=2 AND transactions.successful='f') AND (x.transaction_type=3 AND x.successful='t')
    • 数据库中成功字段的类型是什么??
    • 它是布尔值。 'f' || 't'
    • 我做到了。看评论。我正在使用“f”和“t”
    • 实际上我尝试插入您在问题中编写的示例数据,然后对其运行此查询并正常显示结果
    【解决方案2】:

    您需要使用带有havingwhere 的连接,例如:

        Order.joins(line_items: :transactions).select("orders.*")
    .group("orders.id").having(count(transactions.id) > 2).where(your conditions)
    

    【讨论】:

    • Order.joins(line_items: :transactions).select("orders.*").group("orders.id").having('count(transactions.id) &gt; 2').where("(transactions.transaction_type = 2 AND transactions.successful = 'f') OR (transactions.transaction_type = 3 AND transactions.successful = 't')") 会产生很多结果,因为有些订单可以有多个订单项,每个订单项的交易类型相同且成功。因此,它不会产生正确的结果。
    • 查询仍然产生错误的结果,正如我上面描述的那样。
    猜你喜欢
    • 2017-08-05
    • 2010-10-15
    • 2011-10-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多