I'm trying to make a rails model that contains two different "has_one" attributes of the same class. I feel like there is an easier way to do this, but I can't think of it right now.
So, lets say I'd like to create a wedding model in rails
class Wedding < ActiveRecord::Base
has_one :groom, :class_name => 'Person'
has_one :bride, :class_name => 'Person'
end
class Person < ActiveRecord::Base
attr_accessible :wedding_id
belongs_to :wedding
end
My goal is to have access to the groom object from the wedding object. (be able to call @wedding.groom.name
or whatever) Currently there is no way for the Wedding Model to know which "person" is the Bride and which is the Groom.
Should I be using single table inheretance? Or should I be using foreign keys?
Is there a better way to think of the whole problem?
Your associations are backwards for the functionality that you want..
class Wedding < ActiveRecord::Base
belongs_to :groom, :class_name => 'Person'
belongs_to :bride, :class_name => 'Person'
end
class Person < ActiveRecord::Base
has_many :weddings # who has just one wedding now days???
end
Wedding.find(params[:id]).groom.name
Person.find(params[:id]).weddings.last # hopefully first also :)
Change Person
to Participant
, and give it a role
attribute. Then you can do
class Wedding < ActiveRecord::Base
has_one :groom, :class_name => 'Participant', :condition => "role = 'groom'"
has_one :bride, :class_name => 'Participant', :condition => "role = 'bride'"
end
(Naturally there's no technical reason you need to use Participant instead of Person; it just makes more sense to me that a Participant would have a Role in the Wedding, while a Person is a more general thing. For example, if you wanted to add other roles, you might have a participant with a role of bridesmaid who was the same Person as another participant with a role of, say, caterer.)
Depending on how different they will be treated within the domain, there may be nothing wrong with the approach you have taken.
In the event that 'groom' and 'bride' are mostly naming conventions that are generally treated equally, it may be wiser to simply make a has_many :parties
relationship and let the Person
model determine which is the bride/groom. Perhaps something like this:
class Wedding < ActiveRecord::Base
has_many :parties, :class_name => 'Person'
# helper methods to access bride and groom where specifically needed
def self.groom
parties.where(party_type: Person::GROOM).first
end
def self.bride
parties.where(party_type: Person::BRIDE).first
end
end
class Person < ActiveRecord::Base
attr_accessible :wedding_id, :party_type
GROOM = 'Groom'
BRIDE = 'Bride'
belongs_to :wedding
end
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With