2017-03-14 1 views
1

Ich habe Aufträge mit Status (Pending, und abgeschlossen), Pickup_date, Dropoff_date. Und ich möchte bedingt auf Grund des Status bestellen.Write ActiveRecord Query

  • Wenn der Status Pending lautet, sollte er von pickup_time abgerufen werden.
  • Wenn der Status Completed (abgeschlossen) lautet, sollte er nach dropoff_time sortiert sein.

Antwort

0

Im Modell

scope :pending, -> { where(status: "pending").order(pickup_time: :desc) } 
    scope :completed, -> { where(status: "completed").order(dropof_time: :desc) } 

Dann Order.pending verwenden Sie es durch Abholer es mit allen noch nicht erledigten Aufträge Dann Order.completed verwenden bestellen wird es wird es mit allen conmpleted Bestellungen Bestellung von Drop-Off-Zeit

0

Query using conditionals

Ich empfehle, Bedingungen Abfrage

zu verwenden 0
class Orders < ApplicationRecord 
    scope :order_by_pickup_time, ->(status) { where("created_at < ?", pickup_time) if status == "pending" } 
end 

Wie die anderen Beispiele, wird dies in ähnlicher Weise zu einer Klassenmethode verhalten.

class Orders < ApplicationRecord 
    def self.order_by_pickup_time(status) 
    where("created_at < ?", pickup_time) if status == "pending" 
    end 
end 

Allerdings gibt es eine wichtige Einschränkung: Ein Bereich wird immer wieder zurückkehren ein Active :: Objekt-Beziehung, auch wenn die Bedingung das Ergebnis falsch, während einer Klassenmethode, nil zurück. Dies kann NoMethodError beim Verketten von Klassenmethoden mit Bedingungen verursachen, wenn eine der Bedingungen false zurückgibt.

1

Wir können es in einzelnen Abfrage in Umfang tun, wie:

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") } 
1

würde ich empfehlen nicht Umfang Verantwortung zu mischen. Wenn Sie alles in einem Bereich namens order_by_time tun, ist die Benennung verwirrend, wenn ich Order.order_by_time sehe, werde ich davon ausgehen, dass es nur das Ergebnis bestellt, und ich werde wirklich überrascht sein, wenn ich die Realität nach der Überprüfung der Implementierung ...

ich würde eine Isolierung empfehlen, die mehr Flexibilität für die spätere Verwendung bestimmt:

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) } 

Dann könnte man sie benutzt:

Order.pending.order_by_pickup_time 
Order.completed.order_by_dropof_time