[英]Rails complex joins query
这是我的基本模型层次结构:
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: {}
某种限制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
您可以通过使用范围和合并方法来完成此操作。 范围将使您可以将where条件保持模块化。 通过merge方法,您可以选择接收到InventoryEvent的Inventory。
# 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
我发现了这段SQL,它一直在为我工作:
joins(:inventory_events).where("inventory_events.id IN (SELECT MAX(id) FROM inventory_events GROUP BY inventory_id) AND state = 'received'")
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.