Reputation: 2693
I'm working with two different models Person
and Organization
. Among many other attributes, both a Person
and Organization
can be a Contractor
. If I was working with just the Person
model and wanted to store contractor information I would say that Contractor
belongs_to :person
and be done with it. However this seems like Contractor
belongs to two other models.
I searched around on google and found a lot of info about how to assign ownership to two different models at once. (For example a Sale
must belong to both a Buyer
and a Seller
.) But in my situation a Contractor
is EITHER a Person
or an Organization
. Is there any way to elegantly store Contractor
information for both models in the same table?
If not, I figure I can always make two different contractor tables, but I figured this might be an opportunity to learn something. Many thanks in advance.
Upvotes: 3
Views: 1489
Reputation: 492
I agree with ShallmentMo, but as additional, You could define something like this:
Models
class Contractor < ActiveRecord::Base
belongs_to :contractable, polymorphic: true
...
end
class Person < ActiveRecord::Base
...
has_many :contractors, as: :contractable
...
end
class Organization < ActiveRecord::Base
...
has_many :contractors, as: :contractable
...
end
Migrations
create_table :contractors , force: true do |t|
t.references :contractable, polymorphic: true, index: true
...
t.timestamps null: false
end
Usage
def create
@contractor = Contractor.new(params[:contractor])
contractable = params[:contractor][:contractable].split(":")
@contractor.contractable_type = contractable[0] # String: 'Person' or 'Organization'
@contractor.contractable_id = contractable[1].to_i # Integer: id of 'Person' or 'Organization'
...
Upvotes: 1
Reputation: 449
Maybe you can try this. Rails provide polymorphic-associtions. You can try to build one model named ContractorInfo belongs to Contractable(use polymorphic: true), then Person has_one ContractorInfo as contractable, Organization has_one ContractorInfo as Contractable.
Upvotes: 2