None of the previous answers helped me solve this problem, so I will put this here if anyone else comes across this. Using Rails 4.2 +.
Create a migration (if you already have an address table):
class AddPolymorphicColumnsToAddress < ActiveRecord::Migration def change add_column :addresses, :addressable_type, :string, index: true add_column :addresses, :addressable_id, :integer, index: true add_column :addresses, :addressable_scope, :string, index: true end end
Setting up your polymorphic association:
class Address < ActiveRecord::Base belongs_to :addressable, polymorphic: true end
Set the class from which the link will be called:
class Order < ActiveRecord::Base has_one :bill_address, -> { where(addressable_scope: :bill_address) }, as: :addressable, class_name: "Address", dependent: :destroy accepts_nested_attributes_for :bill_address, allow_destroy: true has_one :ship_address, -> { where(addressable_scope: :ship_address) }, as: :addressable, class_name: "Address", dependent: :destroy accepts_nested_attributes_for :ship_address, allow_destroy: true end
The trick is that you have to call the assembly method in the Order instance or the scope column will not be filled.
So this does NOT work:
address = {attr1: "value"... etc...} order = Order.new(bill_address: address) order.save!
However, it WORKS.
address = {attr1: "value"... etc...} order = Order.new order.build_bill_address(address) order.save!
Hope this helps someone else.