Search code examples
ruby-on-railspolymorphic-associationshas-one

Getting undefined method on build_association for polymorphic has_one association


I'm a newbie and this issue is really frustrating but I have no doubt anyone with experience will see the problem pretty quick.

I am getting an undefined method `build_address' from my CompaniesController. I have a polymorphic has_one relationship to PostalAddress from Company. As part of a sign-up form I am trying to create new company and associated address objects in CompaniesController new method. I am using the correct syntax for build on a has_one.

Models

class Company < ActiveRecord::Base  
  has_one :postaladdress, as: :address, dependent: :destroy
  accepts_nested_attributes_for :postaladdress
end

class PostalAddress < ActiveRecord::Base 
  belongs_to :address, polymorphic: true
end

Controller

class CompaniesController < ApplicationController
  def new
     @company = Company.new
     @address = @company.build_address
  end
end

Migrations

class CreateCompanies < ActiveRecord::Migration
  def change
    create_table :companies do |t|
      t.string :name
      t.string :subdomain

      t.timestamps
    end
  end
end

class CreatePostalAddresses < ActiveRecord::Migration
  def change
    create_table :postal_addresses do |t|
      t.string :addressline1
      t.string :addressline2
      t.string :addressline3
      t.string :town
      t.string :county
      t.string :postcode
      t.string :country

      t.references :address, polymorphic: true;

      t.timestamps
    end
  end
end

Nested Resources in routes.rb

resources :companies do 
  resources :postaladdresses :except => :destroy
end

Solution

  • As you have a has_one association setup between Company and PostalAddress, you would need to use

    @address = @company.build_postal_address

    UPDATE

    Association in Company should look like:

    has_one :postal_address, as: :address, dependent: :destroy
    

    Use postal_address and not postaladdress as your model name is PostalAddress and not Postaladdress

    NOTE:

    Just for reference, if you had has_many association, then it would have been as:

    @address = @company.postal_address.build

    For additional details, read about Auto-generated methods for Associations