has_many:通过与反向关联添加两次

时间:2014-03-05 13:36:43

标签: ruby-on-rails activerecord ruby-on-rails-4 activeadmin inherited-resources

我已经创建了一个示例应用程序来启发我的问题。

基本上,我与STI类有多对多关联:

class Basket < ActiveRecord::Base
  has_many :basket_fruits, inverse_of: :basket
  has_many :fruits, through: :basket_fruits

  has_many :apples, through: :basket_fruits, source: :fruit, class_name: 'Apple'
  has_many :oranges, through: :basket_fruits, source: :fruit, class_name: 'Orange'
  has_many :bananas, through: :basket_fruits, source: :fruit, class_name: 'Banana'
end

class BasketFruit < ActiveRecord::Base
  belongs_to :basket, inverse_of: :basket_fruits
  belongs_to :fruit, inverse_of: :basket_fruits

  validates :basket, :fruit, presence: true
end

class Fruit < ActiveRecord::Base
  has_many :basket_fruits, inverse_of: :fruit
  has_many :baskets, through: :basket_fruits

  validates :type, presence: true, inclusion: ['Apple', 'Banana', 'Orange']

  validates :baskets, presence: true
end

class Apple < Fruit; end
class Banana < Fruit; end
class Orange < Fruit; end

架构:

Basket(id: integer, created_at: datetime, updated_at: date time)
BasketFruit(id: integer, fruit_id: integer, basket_id: integer, created_at: datetime, updated_at: date time)
Fruit(id: integer, type: string, created_at: datetime, updated_at: datetime)

使用ActiveAdmin创建新的Banana时,它使用的代码相当于:

Basket.create
banana = Basket.first.bananas.build(basket_ids: [Basket.first.id])

出现的问题是此代码创建了两个关联,即使不保存Banana也可以观察到这些关联:

banana.basket_fruits.size
=> 2

为什么会发生这种情况,以及如何解决这个问题?

更新

刚发现这个。也许这就是为什么AR试图将关系加两次,而不是像我预期的那样“覆盖”:

banana = Basket.first.bananas.build
=> #<Banana id: nil, type: "Banana", created_at: nil, updated_at: nil>

banana.baskets
=> #<ActiveRecord::Associations::CollectionProxy []>

在这种情况下,需要在调用#build

之后预先填充关联

1 个答案:

答案 0 :(得分:2)

为什么要两次分配篮子?

 Basket.first.bananas.build(basket_ids: [Basket.first.id])

我会这样写:

 Basket.first.bananas.build