#ruby-on-rails
#ruby-on-rails
Вопрос:
У меня настроена ассоциация «многие ко многим» в Rails с ActiveRecord. Допустим, таблицы являются
------------ ---------------- ----------
| categories | -- has many -= | category_items | =- has many -- | products |
------------ ---------------- ----------
В таблице category_items у меня есть стандартный набор идентификаторов плюс дополнительный атрибут под названием «тип»:
id:int
category_id:int
product_id:int
category_type:string
К счастью, Rails предоставляет несколько отличных помощников для упрощения назначения в таблице сопоставления. Например:
p = Product.first # p.id => 1
c = Category.first # c.id => 1
# now to make the assignment
p.categories << c
# or
p.categories.create(c)
Это все хорошо, но, допустим, я хочу автоматически обновить поле «тип» именем класса другой таблицы. Итак, для приведенных выше примеров моя строка category_items будет выглядеть следующим образом:
id = 1 (or some number)
category_id = 1
product_id = 1
category_type = nil
Но я бы хотел, чтобы category_type равнялся «Продукту». Есть ли у меня способ создать обратный вызов или определить что-то в ассоциации, что автоматически установило бы поле category_type? Я знаю, что в полиморфных ассоциациях вы можете использовать что-то вроде:source или:as, чтобы сделать что-то подобное, но полиморфные ассоциации в ассоциациях «многие ко многим» выдают ошибку.
Есть идеи?
Спасибо!
Комментарии:
1. Продукт может иметь более одной категории?
2. да, продукт может иметь более одной категории.
Ответ №1:
Вы пробовали полиморфный метод для category_items, подобный этому:
class CategoryItem < ActiveRecord::Base
belongs_to :category, :polymorphic => true
belongs_to :product
end
class ACategory < ActiveRecord::Base
has_many :category_items, :as => :category
end
class AnotherCategory < ActiveRecord::Base
has_many :category_items, :as => :category
end
class Product < ActiveRecord::Base
has_many :category_items
end
Я думаю, это поможет!
Комментарии:
1. Я не верю, что это сработает. Выдает ошибку HasManyThroughAssociationPolymorphicError при попытке добавить записи. Существует плагин has_many_polymorphs, который, я полагаю, будет работать, но я хотел бы найти решение без плагина, если это возможно.
2. Реальный вопрос, который у меня возникает, заключается в том, как автоматически добавить класс, который я пытаюсь присоединить к категории, в таблицу category_items.
Ответ №2:
В итоге я создал отдельные методы получения / установки. В вашем случае методы в продукте:
установщик
def set_category_type(category_id, type)
category_items = self.category_items.select { |category_item| category_item.category_id == category_id}
if category_items.length > 0
category_item = category_items.first
category_item.type = type
category_item.save
else
CategoryItem.create(:product_id => self.id, :category_id => category_id, :type => type)
end
end
средство получения
def category_type(category_id)
category_item = self.category_items.where(:category_id => category_id ).first()
if category_item.nil?
nil # or some other default type value
else
category_item.type
end
end
В принципе, это было то, что мне было нужно, но я не смог найти более элегантного способа. Пожалуйста, покажите мне лучший способ, если вы знаете.