2014-01-02 3 views
0

У меня есть некоторые модели ActiveRecord настроенные так:Как назначить динамическую переменную в свойстве belongs_to?

Заказать Модель:

class Order < ActiveRecord::Base 
has_many :line_items, :dependent => :destroy 

Line Артикул:

class LineItem < ActiveRecord::Base 
belongs_to :order 
belongs_to :product, :primary_key => "product_id" 

Модель продукта:

class Product < ActiveRecord::Base 

таблиц БД аналогичны этим (колонки опущены для краткости):

заказов:

id | season 
1 | SS14 
2 | SS14 
3 | AW14 

line_items:

id | order_id | product_id 
1 | 1  | 1000 
2 | 1  | 1001 
3 | 2  | 1000 
4 | 3  | 1001 
5 | 3  | 1002 
6 | 3  | 1003 

продукты:

id | product_id | season 
1 | 1000  | SS14  
2 | 1000  | AW14 
3 | 1001  | SS14 
4 | 1002  | SS14 
5 | 1003  | SS14 
6 | 1003  | AW14 

Путь модели устанавливаются означает, что продукт, который присваивается позиции является первый, который он находит, но поскольку могут быть несколько продуктов с одинаковым идентификатором, разделенные морями на, это неверно для этого сценария.

Что мне нужно сделать, так это указать сезон, в котором изделие присвоено, из значения в таблице . Например. если сезон заказа AW14, продукт, назначенный LineItem, должен быть также для AW14. Например. если продукт LineItem составляет 1003, а сезон заказа - AW14, он должен забрать строку с идентификатором: 6, а не ID: 5.

Есть ли способ указать, какой продукт следует использовать в моделях?

TIA.

EDIT:

Я должен добавить, что я могу получить правильный продукт, который будет назначен, если я жестко закодировать сезон в модели LineItem, например:

class LineItem < ActiveRecord::Base 
belongs_to :order 
belongs_to :product, -> { where season: "AW14" }, :primary_key => "product_id" 

Или я могу сделать подобное вещь в default_scope модели продукта, но она должна поступать из Ордера и не быть жестко закодирована.

ответ

2
class LineItem < ActiveRecord::Base 
    belongs_to :order 
    belongs_to :product, :primary_key => 'product_id', :conditions => proc { "season = '#{order.name}'" } 
end 

для LineItem.find (6).продукт будет генерировать SQL, как этот

SELECT "products".* FROM "products" WHERE "products"."product_id" = 1003 AND (season = 'AW14') LIMIT 1 
+0

Блестящий, который отлично работает. Раньше я смотрел на условия и proc, но мое понимание было неправильным, поэтому спасибо за то, что я тоже понял это! – SteveA

0

Может быть, вы могли бы использовать ActiveRecord Association Extension на вашей родительской модели (Order):

#app/models/order.rb 
Class Order < ActiveRecord::Base 
    has_many :line_items, dependent: :destroy 
    has_many :products, through: :line_items do 
     def season(var) 
      where(season: var) 
     end 
    end 
end 

Это позволит вам звонить @orders.products.season(AW2014), который будет возвращать продукты для этого конкретный сезон

в качестве альтернативы, вы можете использовать рамки в Product модели:

#app/models/product.rb 
Class Product < ActiveRecord::Base 
    scope :season, ->(season = nil) { where(season: season) } 
end 

#-> @order.products.season(AW2014) 
+0

Спасибо за быстрый ответ. Я действительно пошел с ответом от @cenyongh, поскольку он работал, как указано, поэтому извините. – SteveA

+0

Нет проблем с приятелем - это помогло мне немного изучить предметные области. Ответ @ cenyongh действительно хорош –

Смежные вопросы