У меня есть анти-шаблон в моем коде 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 соответствуют идентификаторам продуктов картофеля фри и гамбургеров.
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, поэтому я также открыт для стандартного решения SQL, которое игнорирует большую часть ActiveRecord.
Order
,Item' and
ItemOrder`? - person Chirantan   schedule 25.02.2011