如何在未保存的记录之间创建关联

时间:2017-08-02 04:49:25

标签: ruby-on-rails ruby-on-rails-5 cocoon-gem

我创建了3个模型,如下所示,并使用cocoon嵌套形式创建它们之间的关联。

class Unit < ApplicationRecord
  has_many :mapping_categories, -> { distinct }, dependent: :destroy, inverse_of: :unit

  accepts_nested_attributes_for :mapping_categories,
                                allow_destroy: true,
                                reject_if: :all_blank
end

class MappingCategory < ApplicationRecord
  belongs_to :unit
  has_many :mapping_items, -> { distinct }, dependent: :destroy, inverse_of: :mapping_category

  accepts_nested_attributes_for :mapping_items,
                                allow_destroy: true    
end

class MappingItem < ApplicationRecord
  belongs_to :mapping_category
  has_many :mapping_item_links
  has_many :linked_mapping_items, through: :mapping_item_links, dependent: :destroy
end

每个mapping_item可以通过联合表具有许多其他mapping_items。在单位表单的每个mapping_item部分中,此关联显示为选择输入。

创建或更新Unit时,Unit表单中有许多mapping_categories选项卡,每个mapping_category部分中有很多mapping_items部分。

例如,我有映射类别A和映射类别B.我想将映射项1添加到映射类别A并将映射项2映射到映射类别B.问题是:如何创建映射项1和之间的关联映射项目2,因为这两个项目尚未保存? 提前谢谢。

2 个答案:

答案 0 :(得分:0)

从我对你的问题的理解......你做不到。这些项目还没有ID,因此无法与其他模型关联。

> contact = Contact.new(full_name: "Steve", email:"example@asdf.com")
 => #<Contact id: nil, full_name: "Steve", email: "example@asdf.com", created_at: nil, updated_at: nil>

> invoice = Invoice.new(contact_id: contact.id, invoice_type: "Something")
 => #<Invoice id: nil, contact_id: nil, invoice_type: "Something" created_at: nil, updated_at: nil>

> invoice.save
 => false

答案 1 :(得分:0)

你可以做到

你必须写出正确的代码

user = User.new(name: 'Jons', email: 'jons@qq.ww')
bank_account = BankAccount.new(number: 'JJ123456', user: user)
bank_account.save
以这种方式

将同时保存原始内容以及userbank_account

在你的情况下:

unit = Unit.new(mapping_categories: [mapping_category])
mapping_category = MappingCategory.new(mapping_items: [mapping_item])
mapping_item = MappingItem.new
unit.save

如果您想使用nested_attributes,则只需使用属性

构建哈希
params = { mapping_categories: [mapping_items: [{.....}]}] }
Unit.create(params)

但你必须弄清楚正确的嵌套