【发布时间】:2017-08-04 10:28:30
【问题描述】:
我的订单状态为(待处理和已完成)、取货日期、送货日期。 我想根据状态有条件地订购。
- 如果状态为待处理,则应按pickup_time订购。
- 如果状态为 Completed,则应按 dropoff_time 排序。
【问题讨论】:
标签: mysql ruby-on-rails ruby postgresql activerecord
我的订单状态为(待处理和已完成)、取货日期、送货日期。 我想根据状态有条件地订购。
【问题讨论】:
标签: mysql ruby-on-rails ruby postgresql activerecord
我强烈建议不要混合范围职责。如果您在一个名为order_by_time 的范围内完成所有操作,那么命名会令人困惑,如果我看到Order.order_by_time,我会假设它只对结果进行排序,当我在检查实现后了解实际情况时,我会感到非常惊讶。 ..
我建议进行一些隔离,这样可以为以后的使用提供更大的灵活性:
scope :pending, -> { where(status: :pending) }
scope :completed, -> { where(status: :completed) }
scope :order_by_pickup_time, -> { order(pickup_time: :desc) }
scope :order_by_dropof_time, -> { order(dropof_time: :desc) }
那么你就可以使用它们了:
Order.pending.order_by_pickup_time
Order.completed.order_by_dropof_time
【讨论】:
我们可以在范围内的单个查询中做到这一点:
scope :order_by_time, -> { order("CASE WHEN (orders.state IN ('pending', 'picked_up')) THEN 'orders.pick_up_time' WHEN (orders.state IN ('ready_for_delivery', 'delivered')) THEN 'orders.delivery_time' END") }
【讨论】:
我建议使用条件查询
class Orders < ApplicationRecord
scope :order_by_pickup_time, ->(status) { where("created_at < ?", pickup_time) if status == "pending" }
end
与其他示例一样,它的行为类似于类方法。
class Orders < ApplicationRecord
def self.order_by_pickup_time(status)
where("created_at < ?", pickup_time) if status == "pending"
end
end
但是,有一个重要的警告:作用域将始终返回 ActiveRecord::Relation 对象,即使条件评估为 false,而类方法将返回 nil。当使用条件链接类方法时,如果任何条件返回 false,这可能会导致 NoMethodError。
【讨论】:
在模型中
scope :pending, -> { where(status: "pending").order(pickup_time: :desc) }
scope :completed, -> { where(status: "completed").order(dropof_time: :desc) }
然后使用Order.pending它会根据提货时间订购所有挂单
然后使用Order.completed,它会在下车时间之前订购所有已完成的订单
【讨论】: