0

これが私の基本的なモデル階層です。

class Product
  has_many :inventories
end
class Inventory
  belongs_to :product
  has_many :inventory_events
end
class InventoryEvent
  belongs_to :inventory
end

InventoryEvent インスタンスは、状態の変更とそれらの変更のタイムスタンプを格納するためinventory.inventory_events.last、現在の状態が表示されます。

現在の状態received

私が今持っているものは次のとおりです。

p = Product.first
p.inventories.joins(:inventory_events).where(inventory_events: {state: 'received'}).all

=> # Here I get back all Inventory that ever had the state 'received' but may 
not currently be 'received'.

私のSQLの知識はかなり限られていますが、オプションに対するある種の制限がinventory_events: {}機能するようですが、それを行う方法は見つかりませんでした.


編集:私の最終目標を示すためだけに、現時点での私の回避策を次に示します。このようなクエリをモデル化する方法があることを願っています。

class Inventory
  def self.received_items
    includes(:inventory_events).select {|i| i.current_state == 'received'}
  end
  def current_state
    inventory_events.last.state
  end
end

Product.first.inventories.received_items
=> # Here I get the correct array of inventories
4

2 に答える 2

0

これは、スコープとマージ メソッドを使用して実現できます。スコープを使用すると、where 条件をモジュール化することができます。マージ メソッドを使用すると、受信した InventoryEvent を持つインベントリを選択できます。

# call this to get the inventories for the product that have been recieved
product.inventories.received

class InventoryEvent
  def self.received
    where("state = ?", "received")
  end

  def self.most_recent
    order("inventory_events.created_at desc").first
  end
end

class Inventory
  def self.received
    joins(:inventory_events).
    merge(InventoryEvent.received).
    merge(InventoryEvent.most_recent)
  end
end
于 2013-09-04T00:29:09.153 に答える