【发布时间】:2011-02-25 05:08:28
【问题描述】:
我的 Rails 3 代码中有一个反模式,我想知道如何正确地做到这一点。
假设客户订购了炸薯条和汉堡包。我想知道以前是否下过这样的订单。为简单起见,每个订单只能订购一次(所以没有“请两个汉堡包”),也没有重复订单。
型号:
Order (attributes: id)
has_many :items_orders
has_many :items, :through => :items_orders
Item (attributes: id, name)
has_many :items_orders
has_many :orders,:through => :items_orders
ItemsOrder (attributes: id, item_id, order_id)
belongs_to :order
belongs_to :item
validates_uniqueness_of :item_id, :scope => :order_id
我现在的做法是获取至少包含一个订单项的所有订单。然后我遍历它们以找到匹配的顺序。不用说,它的扩展性不好,看起来也不漂亮。
order = [1, 2]
1 和 2 对应薯条和汉堡的 Item id。
candidates = Order.find(
:all,
:include => :items_orders,
:conditions => ["items_orders.item_id in (?)", order])
previous_order = nil
candidates.each do |candidate|
if candidate.items.collect{|i| i.id} == order
previous_order = candidate
break
end
end
我正在使用 MySQL 和 Postgress,因此我也愿意接受忽略大部分 ActiveRecord 的标准 SQL 解决方案。
【问题讨论】:
-
能否列出
Order、Item' andItemOrder`的属性和关系? -
@SjorsProvoost 我下面的回答有帮助吗?如果您有任何问题,请告诉我?
-
@PaulRussell 它肯定会比我现在拥有的要快得多,谢谢。我只是希望有一个不需要冗余的解决方案(或者至少一个让数据库来处理)。
标签: mysql ruby-on-rails activerecord anti-patterns