I'm trying to make it possible to add multiple crops
to a spray_program
through program_crops
in a nested form using cocoon. I'm able to add one but the link_to_add_association button just adds # to the url. Ill add the bits of code I think will be relevant let me know if there is something else...
nested form in spray_program form
<div id="programCrops">
<%= form.fields_for :program_crops do |program_crop_form| %>
<%= render 'program_crop_fields', f: program_crop_form%>
<% end %>
</div>
<div >
<%= link_to_add_association "Add crop", form, :program_crops %>
</div>
_program_crop_fields.html.erb
<div >
<div >
<%= f.label :name %>
<%= f.collection_select :crop_id, Crop.all, :id, :name %>
</div>
<%= link_to_remove_association "Remove crop", f %>
</div>
I suspect building the model only once here may be the issue and this needs to be passed elsewhere
def new
@spray_program = SprayProgram.new
@spray_program.build_program_sprayer
@spray_program.program_crops.build
end
the model
class ProgramCrop < ApplicationRecord
belongs_to :crop
belongs_to :spray_program
validates :spray_program, uniqueness: { scope: :crop }
end
No JavaScript errors being thrown in console. The dropdown renders correctly and creates one many to many association as expected. Sorry if I've missed something important it's getting late!
CodePudding user response:
without the other model I can't answer for sure, but I suspect that you are missing either accepter_nested_attributes_for
or inverse_of
, check the note under Basic Usage in here, https://www.rubydoc.info/gems/cocoon/1.2.12
Rails 5 Note: since rails 5 a belongs_to relation is by default required. While this absolutely makes sense, this also means associations have to be declared more explicitly. When saving nested items, theoretically the parent is not yet saved on validation, so rails needs help to know the link between relations. There are two ways: either declare the belongs_to as optional: false, but the cleanest way is to specify the inverse_of: on the has_many. That is why we write : has_many :tasks, inverse_of: :project
This basically allows to have a reference to an object on the new action, without having that objects id(because it hasn't been created yet), by building the object you are giving the data to the form, but the form doesn't know how to link them, so you end up sending back to the backend two objects that don't reference each other
CodePudding user response:
https://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html
Please review this, you need to tell the modal that you are accepting nested attributes, cocoon works this way, if you still not finding the solution, please share other modal too