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显示当前状态。

在 Product 模型上创建查询时遇到问题,该查询将为我提供当前状态为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 回答
0

我发现了这段 SQL,它一直在为我工作:

joins(:inventory_events).where("inventory_events.id IN (SELECT MAX(id) FROM inventory_events GROUP BY inventory_id) AND state = 'received'")
于 2013-09-16T22:49:43.647 回答