Reputation: 1282
I'm using simple_form with cocoon (https://github.com/nathanvda/cocoon) and everything works pretty well.
The only thing I really really dislike is the fact that I have to initialize empty instances to make it work:
def new
@facility = Facility.friendly.find(params[:facility_slug])
@pet = @facility.pets.build(animal: Dog.new)
@pet.pet_pictures.build
@pet.animal.mixtures.build
end
The last 2 lines are for making cocoon and link_to_add_association work, if I remove them link_to_add_association is completely empty.
Does anybody know how to make this a little bit more idiomatic and avoid explicitly call the build method? How can I improve this code?
Upvotes: 1
Views: 970
Reputation: 76774
How can I improve this code?
By putting the code in the model:
#app/models/facility.rb
class Facility < ActiveRecord::Base
def construct_pet animal
model = animal.to_s.constantize
pet = pets.build animal: model.send(:new)
pet.pet_pictures.build
pet.animal_mixtures.build
pet
end
end
#app/controllers/facilities_controller.rb
class FacilitiesController < ApplicationController
def new
@facility = Facility.find(params[:facility_slug]).construct_pet(:dog)
end
end
The problem you have is not with cocoon, it's Rails.
Let me explain:
fields_for
You must remember that rails is object orientated, in every sense of the term.
This means that if you want to create dependent data (IE nested fields), you'll have to build the relevant associated model instances.
There is no getting around this; if you don't build the models, Rails will simply not know how to construct the fields_for
methods.
When you create an associated model (IE pass data with accepts_nested_attributes_for
), Rails has to have instances of the related models to pass.
If you don't build the dependent models, you don't get any related fields, and thus it won't work.
Cocoon uses fields_for
in exactly the same way as you would if you "manually" did it:
You can see from this RailsCast and this answer I literally just wrote.
--
avoid explicitly call the build method
N'est pas possible, mon ami.
The build
method creates instances of the instances associative models. If you don't want them to show (which is required to get fields_for
working), you won't be able to use them.
Upvotes: 1