I have a model called Family, which belongs_to User I want to enable the user to add multiple family members in a single form, which is in
You need to tweak your code like this.Assuming you have the attribute name
in users table.
In your User model
class User < ActiveRecord::Base
has_many :families, :dependent => :destroy
accepts_nested_attributes_for :families, :allow_destroy => true
end
In your users_controller
def new
@user = User.new
@family = 3.times { @user.families.build } #here
end
Your strong parametrs should look like this
def user_params
params.require(:user).permit(:name, families_attributes: [:name,:email])
end
#users/new.html.erb
<%= form_for(@user) do |f| %>
<div class="field">
<%= f.label :name %><br />
<%= f.text_field :name %>
</div>
<%= f.fields_for :familes do |builder| %>
<%= render 'family_fields', :f => builder %>
<% end %>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
#users/_family_fields.html.erb
<div>
<%= f.label :name, "Name" %>
<%= f.text_field :name %>
<br>
<%= f.label :email, "Email" %>
<%= f.text_field :email %>
</div>
You want to use nested forms
. You should be able to copy and paste the following code to get going:
app/models/family.rb
class Family < ActiveRecord::Base
has_many :users
accepts_nested_attributes_for :users
end
app/models/user.rb
class User < ActiveRecord::Base
belongs_to :family
end
app/views/families/new.html.erb
<%= form_for(@family) do |f| %>
<%= f.fields_for :users do |user| %>
<p>
<%= user.text_field :name %><br>
<%= user.text_field :email %>
</p>
<% end %>
<%= f.submit %>
<% end %>
app/controllers/families_controller.rb
[...]
def new
@family = Family.new
3.times { @family.users.build }
end
[...]
private
# Use callbacks to share common setup or constraints between actions.
def set_family
@family = Family.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def family_params
params.require(:family).permit(:name, users_attributes: [ :name, :email ])
end
The way that i always do this is to make a new action update_multiple
. This expects params with the following structure (using your Family example, and updating two records, with ids 123 and 456)
params = {:families => {123 => {:name => "foo", :address => "bar"}, 456 => {:name => "baz", :address => "qux"} }}
and the action works like so:
@families = []
params[:families].each do |id, attributes|
if family = Family.find_by_id(id)
family.update_attributes(attributes)
@families << family
end
end
In order to set up the params with the required structure, your form would be set up like so:
<% @families.each do |family| %>
<div class="family">
<label>Name: <%= text_field_tag "families[#{family_id}][name]", family.name %></label>
<label>Address: <%= text_field_tag "families[#{family_id}][address]", family.address %></label>
</div>
<% end %>
You could, instead of making a new action, change the structure of your update
action to do the standard code if it gets params[:family] and the above code if it gets params[:families].