My nested model form is now working, but I am having trouble displaying the data in a view. How do I display nested model data with a one-to-many relationship? Any help will be greatly appreciated.
Here’s my form and controller:
<%= form_for @account do |f| %>
<%= f.label :account_type %><br />
<%= f.text_field :account_type %><br />
<%= f.fields_for :organizations do |builder| %>
<%= builder.label :name %><br />
<%= builder.text_field :name %><br />
<%= builder.label :website %><br />
<%= builder.text_field :website %><br />
<%= builder.fields_for :locations do |lb| %>
<%= lb.label :phone %><br />
<%= lb.text_field :phone %><br />
<%= lb.label :toll_free_phone %><br />
<%= lb.text_field :toll_free_phone %><br />
<%= lb.label :fax %><br />
<%= lb.text_field :fax %><br />
<%= lb.fields_for :addresses do |ab| %>
<%= ab.label :address1 %><br />
<%= ab.text_field :address1 %><br />
<%= ab.label :address2 %><br />
<%= ab.text_field :address2 %><br />
<%= ab.label :city %><br />
<%= ab.text_field :city %><br />
<%= ab.label :state %><br />
<%= ab.text_field :state %><br />
<%= ab.label :zip %><br />
<%= ab.text_field :zip %><br />
<% end %>
<% end %>
<% end %>
<%= f.submit "Add account" %>
<% end %>
class AccountsController < ApplicationController
def show
@account = Account.find(params[:id])
@organization = @account.organizations
end
def new
@account = Account.new
organization = @account.organizations.build
location = organization.locations.build
location.addresses.build
@header = "Create account"
end
def create
@account = Account.new(params[:account])
if @account.save
flash[:success] = "Account added successfully"
render 'show'
else
render 'new'
end
end
end
In general, how do I reference nested model data in a view when there is one-to-many relationship? Do I need to specify the child with some type of “where clause” like method?
Here is a simple example show.html.erb where I am trying to display the Name of the Organization that I just created. It doesn’t work.
<h1><%= @organization.name %></h1>
The render ‘show’ action after creating an Account with the above form results in this error:
NoMethodError in Accounts#create
Showing C:/Documents and Settings/Corey Quillen/My
Documents/rails_projects/shop_manager/app/views/accounts/show.html.erb where line #1
raised:
undefined method `name' for nil:NilClass
Extracted source (around line #1):
1: <h1><%= @organization.name %></h1>
Rails.root: C:/Documents and Settings/Corey Quillen/My
Documents/rails_projects/shop_manager
Application Trace | Framework Trace | Full Trace
app/views/accounts/show.html.erb:1:in
`_app_views_accounts_show_html_erb__790921876_14235864__946051513'
app/controllers/accounts_controller.rb:21:in `create'
Request
Parameters:
{"utf8"=>"✓",
"authenticity_token"=>"y59rGAhS+kqfH3v3axhlYuxvBbBxIWXg0yucCFwfBq8=",
"account"=>{"account_type"=>"dfdf",
"organizations_attributes"=>{"0"=>{"name"=>"dfdf",
"website"=>"dfdf",
"locations_attributes"=>{"0"=>{"phone"=>"dfdf",
"toll_free_phone"=>"dfd",
"fax"=>"",
"addresses_attributes"=>{"0"=>{"address1"=>"",
"address2"=>"",
"city"=>"",
"state"=>"",
"zip"=>""}}}}}}},
"commit"=>"Add account"}
You say @organization = @account.organizations in your show action.
Just what are you expecting @organization to contain?
Think about it. It’s going to be an array not a single organization so loop through that and get the name for each organization
Actually I think you haven’t thought your relationships through properly surely an account belongs_to an organisation. Do you really want an account to be associated with more than one organisation ?
UPDATE – Ref comment below
That is totally possible to do but you need to decide what the business logic is that determines which organisation needs to be displayed here.
If you can explain exactly how your relationships are supposed to work it shouldn’t be too difficult to show you how to apply your logic
UPDATE – How to get the primary organisation
This is simply a matter of setting up a new association on the Account model
Then in your show action just write
You might also want to check that primary_organization is not empty?
Consider refactoring that has_one into a class method. May not be necessary depending on your needs
Read more here http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html