Обновите атрибут таблицы сопоставления в ассоциации «многие ко многим» - PullRequest
4 голосов
/ 15 апреля 2011

У меня есть много ко многим, в Rails настроена ассоциация с ActiveRecord.Скажем, таблицы

+------------+                +----------------+                +----------+
| categories | -- has many -= | category_items | =- has many -- | products | 
+------------+                +----------------+                +----------+

В таблице category_items у меня есть стандартный набор идентификаторов плюс дополнительный атрибут с именем "type":

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 равнялся «Product».Есть ли способ для меня создать обратный вызов или определить что-то в ассоциации, которая автоматически установит поле category_type?Я знаю, что в полиморфных ассоциациях вы можете использовать что-то вроде: source или: as, чтобы сделать что-то подобное, но полиморфные ассоциации во многих ассоциациях приводят к ошибке.

Любые идеи?

Спасибо!

Ответы [ 2 ]

1 голос
/ 15 апреля 2011

Вы пробовали полиморфизировать элементы category_, как это:

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

Я думаю, это поможет!

0 голосов
/ 25 января 2014

В итоге я сделал отдельные методы получения / установки. В вашем случае методы по продукту:

сеттер

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

Это было в основном то, что мне было нужно, но я не мог найти более элегантный способ. Пожалуйста, покажи мне лучший способ, если знаешь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...