Ruby Nested Form

Triple-nested form with Rails form_with and strong parameters

At first, you need to change the form to nest option_values inside option, and add account_id field to option values:

<%= form_with(model: product, local: true) do |f| %>
<%= f.fields_for :options do |options_form| %>
<fieldset class='form-group'>
<%= options_form.hidden_field :account_id, value: current_user.account.id %>
<%= options_form.label :name, 'Option' %>
<%= options_form.text_field :name, class: 'form-control' %>
</fieldset>

<%= options_form.fields_for :option_values do |values_form| %>
<fieldset class='form-group'>
<%= values_form.hidden_field :account_id, value: current_user.account.id %>
<%= values_form.label :name, 'Value' %>
<%= values_form.text_field :name, class: 'form-control' %>
</fieldset>
<% end %>
<% end %>
<% end %>

Also you need to build nested records in the controller. Another option is to build them dynamically via javascript (look at the cocoon gem, for example). To build 3 options with 3 values each:

def new 
@account = current_user.account
# it is better to create associated product
@product = @account.products.new
3.times do
option = @product.options.build
3.times { option.option_values.build }
end
end

Rails Multiple Nested Forms

The new form_with which combines the previous form_for and form_tag makes it on the one hand pretty powerful but also sometimes very confusing. What used to be simply form_for @product, now you have to write

form_with model: @product, local: true do |f|

Your use of scope: just uses @product as a prefix and will not actually iterate over or use the @product to find associations, that is why we do not see the property_attributes, nor the implicit id field, even though you correctly have the accepts_nested_attributes (the _destroy field would be added by cocoon's link_to_remove_association --if you would want to go back to the ability to dynamically add/remove nested items).

Rails 2 level nested forms

Your strong parameters permit call should reflect the actual nesting structure of parameters:

def person_params
params.require(:person).permit(
:first_name, :last_name,
addresses_attributes: [
:id, :kind, :street, :_destroy,
{ nested_addresses_attributes: [:id, :name, :_destroy] } # <= note the hash
]
)
end

How to pass an account_id through a nested form in Rails

Alternatively, you can pass a hidden_field with form and nested_form as given below: -

<%= form_for @product do |form|%>
<%= form.fields_for :options do |builder| %>
<fieldset class='form-group'>
<%= builder.label :name, 'Add option(s)' %>
<%= builder.text_field :name %>
<small id="optionHelp" class="form-text text-muted">
(e.g. "Sizes" or "Color")
</small>
<%=builder.hidden_field :account_id, value: current_user.account.id%>
</fieldset>
<% end %>
<%= form.hidden_field :account_id, value: current_user.account.id%>
<%end%>

Other than this you can set account_id at the controller

  def new
#@product = Product.new
@product = current_user.account.products.new
@product.options.build(account_id: current_user.account.id)
end

Rails 6: Nested Form not saving

The Poll isn't created at the moment the validations in the Question model are run and so the question's poll_id is nil causing the presence validation to fail. You can remove the validation since the belongs_to :poll association validates that the poll exists (belongs_to association is required by default from Rails 5).

class Question < ApplicationRecord
belongs_to :poll
validates_presence_of :content
end


Related Topics



Leave a reply



Submit