Creating multiple polymorphic rails records at once

I have the exact same scheme as described here with a polymorphic compound table: http://aaronvb.com/articles/a-polymorphic-join-table.html

class Location < ActiveRecord::Base has_many :note_joins, as: :notable has_many :notes, through: :note_joins end class Checkpoint < ActiveRecord::Base has_many :note_joins, as: :notable has_many :notes, through: :note_joins end class NoteJoin < ActiveRecord::Base belongs_to :notable, polymorphic: true belongs_to :note end class Note < ActiveRecord::Base attr_accessible :content, :user_id belongs_to :notable, polymorphic: true belongs_to :user has_many :note_joins end 

I want to be able to create and update several types of polymorphic associations at once, instead of doing @note.locations << Location.first or @note.checkpoints << Checkpoint.first .

Something like @note.create note_joins_params and @note.update note_joins_params would be awesome.

So far, I have managed to achieve the creation part by passing an array of attributes @note.note_joins.create , for example.

 note_joins_params = [{"notable_id"=>"9225", "notable_type"=>"Location"}, {"notable_id"=>"9220", "notable_type"=>"Checkpoint"}] @note.note_joins.create note_joins_params 

Is there still a Rails-esque way to achieve this, or a valid attribute hash syntax similar to accepts_nested_attributes or something similar?

Also the only way to learn how to update is to delete all existing entries in the connection table first and then recreate them, i.e.

 @note.note_joins.destroy_all new_note_joins_params = [{"notable_id"=>"9225", "notable_type"=>"Location"}, {"notable_id"=>"9220", "notable_type"=>"Checkpoint"}] @note.note_joins.create new_note_joins_params 
+6
source share
1 answer

For what you want to achieve, Rails does not have this "smart_way" to accept nested attributes unless you specify source_type . See This Other Side of the Polymorphic: Through Associations

But you can try the following:

 class Location < ActiveRecord::Base has_many :note_joins, as: :notable has_many :notes, through: :note_joins accepts_nested_attributes_for :notes end class Checkpoint < ActiveRecord::Base has_many :note_joins, as: :notable has_many :notes, through: :note_joins accepts_nested_attributes_for :notes end class NoteJoin < ActiveRecord::Base belongs_to :notable, polymorphic: true belongs_to :note accepts_nested_attribute_for :note end class Note < ActiveRecord::Base attr_accessible :content, :user_id belongs_to :user has_many :note_joins # add these, otherwise you won't be able to do nested attributes # refer to the blog post I link above. has_many :locations, through: :note_joins, source: :notable, source_type: 'Location' has_many :checkpoints, through: :note_joins, source: :notable, source_type: 'Checkpoint' end 

Then in your form create something like this:

 # In your form # if you want to create from the note, do this <%= form_for @note do |f| %> <%= f.text_field :some_note_field %> <%= text_field_tag 'note[locations_attributes][][some_location_field]' %> <%= text_field_tag 'note[checkpoints_attributes][]some_checkpoint_field]' %> <% end %> # if you want to create from the location/checkpoint, do this. <%= form_for @location do |f| %> <%= f.text_field :name %> <%= text_field_tag 'location[notes_attributes][][body]' %> <% end %> # In your Location/Checkpoint controllers def create @location = Location.create(location_params) redirect_to @location end def location_params params.required(:location).permit(:name, notes_attributes: [:body]) end # In your Note controller def create @note = Note.create(note_params) redirect_to @note end def note_params # the goal here is to create a set of params like this # { note_field: 'foobar', # locations_attributes: [{name: 'somewhere'}], # checkpoints_attributes: [{description: 'lol'}] } params.required(:note).permit(:note_field, locations_attributes: [:location_field], checkpoints_attributes: [:checkpoint_field]) end 
+6
source

Source: https://habr.com/ru/post/1013441/


All Articles