Search code examples
ruby-on-railsruby-on-rails-5cocoon-gem

How to create association between unsaved records


I created 3 models as below, and used cocoon nested form to create associations between them.

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

Each mapping_item can have many other mapping_items through a joint table. In every mapping_item section in Unit form, this association is displayed as a select input.

When creating or updating Unit, there are many mapping_categories tabs in the Unit form, and there are many mapping_items sections in each mapping_category section.

For example, I have Mapping Category A and Mapping Category B. I want to add Mapping Item 1 to Mapping Category A and Mapping Item 2 to Mapping Category B. The question is: How to create the association between Mapping Item 1 and Mapping Item 2, as these two items are not saved yet? Thanks in advance.


Solution

  • From my understanding of your question... You can't. These items don't yet have ids and there for can't be associated with another model.

    > 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