I am stuck up with building nested forms using Ruby on Rails.
I am trying to build a form which has fields from three tables(User, Contact, Address
). User table has address_id
and contact_id
. When user fills the details, contact details should be saved in contact
table and address should be saved in address
table. Both the ids should get saved in user table along with the user details. How should I proceed?
My model,
class Address < ApplicationRecord
has_one :user
end
class Contact < ApplicationRecord
has_one :user
end
class User < ApplicationRecord
belongs_to :address
belongs_to :contact
end
My controller,
class UsersController < ApplicationController
def new
@user = User.new
@user.build_contact
@user.build_address
end
def create
@user = User.new(user_params)
respond_to do |format|
if @user.save
format.html { redirect_to @user, notice: 'User was successfully created.' }
format.json { render :show, status: :created, location: @user }
else
format.html { render :new }
format.json { render json: @user.errors, status: :unprocessable_entity }
end
end
end
private
def user_params
params.require(:user).permit(:name, :email, contact_attributes: [:phone], address_attributes: [:street, :city])
end
end
And my view is,
<%= form_for(user) do |f| %>
<% if user.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(user.errors.count, "error") %> prohibited this user from being saved:</h2>
<ul>
<% user.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :name %>
<%= f.text_field :name %>
</div>
<div class="field">
<%= f.label :email %>
<%= f.text_field :email %>
</div>
<%= f.fields_for :contact do |c| %>
<div class="field">
<%= c.label :phone %>
<%= c.text_field :phone %>
</div>
<% end %>
<%= f.fields_for :address do |a| %>
<div class="field">
<%= a.label :street %>
<%= a.text_field :street %>
</div>
<div class="field">
<%= a.label :city %>
<%= a.text_field :city %>
</div>
<% end %>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
Is my approach right? Kindly please suggest. Thanks in advance.
You missing a couple of lines...
class User < ApplicationRecord
belongs_to :address
belongs_to :contact
accepts_nested_attributes_for :address
accepts_nested_attributes_for :contact
end
Also ensure you accept :id
and :_delete
params.require(:user).permit(:name, :email, contact_attributes: [:id, :phone, :_delete], address_attributes: [:id, :street, :city, :_delete]