Corey Quillen
Corey Quillen

Reputation: 1576

Nested model forms with polymorphic association

I am having more trouble with nested forms. This time with my polymorphic Address model. Any help will be greatly appreciated.

<%= 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 :address 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 Account < ActiveRecord::Base

    has_many :organizations

    accepts_nested_attributes_for :organizations
end

class Organization < ActiveRecord::Base

    belongs_to :account

    has_many :locations

    accepts_nested_attributes_for :locations
end

class Location < ActiveRecord::Base

    belongs_to :organization

    has_one :address, :as => :addressable

end

class Address < ActiveRecord::Base

    belongs_to :addressable, :polymorphic => true
end

class AccountsController < ApplicationController

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
        #handle success
    else
        render 'new'
    end
end
end

When trying to display the form via /accounts/new I am getting the following error message:

NoMethodError in AccountsController#new

undefined method `addresses' for #<Location:0x18d7718>
Rails.root: C:/Documents and Settings/Corey Quillen/My     
Documents/rails_projects/shop_manager

Application Trace | Framework Trace | Full Trace
app/controllers/accounts_controller.rb:7:in `new'
Request

Parameters:

None

Upvotes: 1

Views: 1314

Answers (1)

Ryan Bigg
Ryan Bigg

Reputation: 107708

The problem is because you're doing location.addresses.build when you've defined the Address association for this model as a has_one. As such, you will need to do location.build_address. The same thing goes for if you were ever looking to build a belongs_to association.

It is not possible for the build method to be called on the address association itself, as the address method would attempt to load the associated object and return nil if it can't, and calling build on nil is just not allowed. Therefore, you need to do build_address.

Upvotes: 1

Related Questions