简体   繁体   English

更新多对多关联中的映射表属性

[英]Update Mapping Table Attribute in Many to Many Association

I have a many to many association setup in Rails with ActiveRecord. 我在Rails中使用ActiveRecord进行了多对多的关联设置。 Let's say the tables are 我们说这些表是

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

In the category_items table I have the standard set of id's plus an extra attribute called "type": 在category_items表中,我有标准的id集和一个名为“type”的额外属性:

id:int 
category_id:int
product_id:int
category_type:string

Thankfully, Rails provides some great helpers for making assignment in the mapping table a breeze. 值得庆幸的是,Rails提供了一些很好的帮助,使得在映射表中进行赋值变得轻而易举。 For example: 例如:

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)

That's all well and good, but let's say I want to automatically update the "type" field with the class name of the other table. 这一切都很好,但是我想说我想用另一个表的类名自动更新“type”字段。 So for the examples given above, my category_items row would look like this: 因此,对于上面给出的示例,我的category_items行将如下所示:

id = 1 (or some number)
category_id = 1 
product_id = 1
category_type = nil

But I would like category_type to equal "Product". 但我希望category_type等于“Product”。 Is there a way for me to build a callback or define something in the association that would automatically set the category_type field? 有没有办法让我在关联中构建一个回调或定义一些会自动设置category_type字段的东西? I know in polymorphic associations, you can use something like :source or :as to do something like this, but polymorphic associations in many to many associations throws an error. 我知道在多态关联中,你可以使用类似:source或:as做类似的事情,但是多对多关联中的多态关联会引发错误。

Any ideas? 有任何想法吗?

Thanks! 谢谢!

Have you tried a polymorphic on category_items like this: 你有没有在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

I think this will do the trick! 我认为这样就可以了!

I ended up making separate getter/setter methods. 我最终制作了单独的getter / setter方法。 In your case, methods on Product: 在您的情况下,产品上的方法:

setter 二传手

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

getter 吸气

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

This was basically what I needed but couldn't find a more elegant way. 这基本上是我需要的,但找不到更优雅的方式。 Please show me a better way if you know. 如果你知道,请告诉我一个更好的方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM