Mel
Mel

Reputation: 2687

Rails: polymorphic associations

I am building an app with Rails 4.

I have an address model and a phone model. Each of them are defined as polymporphic with a number of other models, so that they can be used across the application- for example, a user has phone number, but so does a company. They numbers could be different. The company has an address and it can be used by the user as a default, or they can add another one as their own.

In my code, I have an address model as:

class Address < ActiveRecord::Base

  geocoded_by :full_address_map   # can also be an IP address


  # --------------- associations

  belongs_to :addressable, :polymorphic => true

  # --------------- scopes

  # --------------- validations

  validates_presence_of :unit, :street, :zip, :country 


  # --------------- class methods

  def first_line
    [unit, street].join(' ')
  end

  def middle_line
    if self.building.present? 
    end
  end

  def last_line
    [city, region, zip].join('   ')
  end

  def country_name
    self.country = ISO3166::Country[country]
    country.translations[I18n.locale.to_s] || country.name
  end

  def address_without_country
    [self.first_line, middle_line, last_line].compact.join(" ")
  end

  def full_address_map
    [self.first_line, middle_line, last_line, country_name.upcase].compact.join("<br>").html_safe
  end

  def full_address_formal
    [self.first_line, middle_line, last_line, country_name].compact.join(" ").html_safe
  end


  # --------------- callbacks

  after_validation :geocode#, if  self.full_address.changed? 

  # --------------- instance methods

  # --------------- private methods

  protected

end

In my address _form partial, I have the form for users to complete.

In my organisations model, I have:

class Organisation < ActiveRecord::Base

  # --------------- associations

    has_one :user # the user that is the representative 
    has_many :profiles # the users who have roles within the org


    has_many :addresses, :as_addressable
    has_many :phones, :as_phoneable


  # --------------- scopes



  # --------------- validations

  # --------------- class methods


  def address
    self.address.full_address_formal
  end


  # --------------- callbacks

  # --------------- instance methods

  # --------------- private methods


end

In my organisation controller, new action, I have:

def new
    @organisation = Organisation.new
    @organisation.build_address
end

When I try this, I have this error:

NoMethodError at /organisations/new
undefined method `arity' for :as_addressable:Symbol

In my address table, I have:

t.integer  "addressable_id"
t.string   "addressable_type"
add_index "addresses", ["addressable_type", "addressable_id"], name: "index_addresses_on_addressable_type_and_addressable_id", unique: true, using: :btree

I don't understand the nature of the error. What is this structure missing?

Upvotes: 0

Views: 111

Answers (1)

messanjah
messanjah

Reputation: 9278

Polymorphic associations require the as option in their declarations.

has_many :addresses, as: :addressable
has_many :phones, as: :phoneable

Upvotes: 1

Related Questions