订单AutoSort()
order_events。
has_many
是订单状态的记录,例如order_event
,pending_approval
等。
通过创建confirmed
跟踪订单的更改。
我通常通过执行以下操作来获取订单的当前状态:order_events
。
我想查询以获取具有给定当前状态的所有订单,例如,当前状态为order.order_events.last.try(:state)
的所有订单。
我最初在cancelable
模型中有一个范围:
OrderEvent
然后是scope :cancelable, -> { where('state = ? OR state = ?', 'pending_approval', 'pending_confirmation') }
模型中的范围:
Order
并简单地将后者用于其他目的。
这里的问题是它返回当前或过去满足条件的所有订单。
获得目前满足条件的所有订单的最佳方法是什么?
答案 0 :(得分:2)
我最终使用了这样的查询:
scope :with_dates_and_current_state_cancelable, -> {
with_dates
.joins(:order_events)
.where('order_events.created_at = (SELECT MAX(order_events.created_at) FROM order_events WHERE order_events.order_id = orders.id)')
.where('order_events.state = ? OR order_events.state = ?', 'pending_approval', 'pending_confirmation')
.group('orders.id')
}
有点难以阅读,但似乎有效。
答案 1 :(得分:0)
这里的经典解决方案是使用Rails enum。
将此添加到您的订单型号:
class Order
enum status: [ :pending_approval, :confirmed, etc.. ]
...
end
可以通过执行以下操作来更改状态:
# order.update! status: 0
order.pending_approval!
order.pending_approval? # => true
order.status # => "pending_approval"
不需要order_events
模型。
查询待批准的所有订单:
Order.where(status: :pending_approval)
编辑:
order_event
有必要列时的替代解决方案。
在名为order_event
的{{1}}中添加一列,可以设置为1或0.将archived
模型中的默认范围设置为:
order_event
假设0未归档。
现在,当您创建新订单事件时,将旧事件设置为1。
default_cope where(:archived => 0)
每当您查询等待审核时:
old_event = OrderEvent.find(params[:order_id])
old_event.update(archived: 1)
new_event = OrderEvent.create(...archived: 0)
仅显示未归档的事件。
答案 2 :(得分:0)
我想我找到了一个可能有用的查询。我没有将它转换为ActiveRecord
方法,但这里是:
SELECT t.order_id
FROM
(SELECT MAX(created_at) AS created, order_id
FROM order_events
GROUP BY order_id) as t
INNER JOIN order_events
ON t.order_id = order_events.order_id AND
t.created = order_events.created_at
WHERE order_events.state = 'whatever_state_you_want'