7

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?

3 Answers 3

9

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 :) 
Sign up to request clarification or add additional context in comments.

5 Comments

"who has just one wedding now days???" - LOL. I think the intention here is to assist the wedding planner, not the individual people manage their lives...
I know.. :) couldn't resist.. change the above to a has_one and we can all believe that love will last forever! :)
I guess I was trying to avoid putting all the foreign keys on the wedding model, but you're right, that would work.
What was the reason for the avoidance? Put the foreign keys where they are meant to be! (I have only been married once)
It's the phrasing of these things that throws me. A Wedding doesn't "belong to" a person, conceptually a wedding "has_one" bride and groom. But yeah, most straighforward fix is to flip them. Good answer.
2

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.)

2 Comments

Hmm.. :condition is a good call. That may be what I'm looking for. Lets say I have a groom which is a 'Participant'. I then set @wedding.groom = groom and save the wedding. When I next load the wedding and call @wedding.groom.name, will that /know/ which Participant object I want?
Yes. The content of the :condition becomes the SQL where clause when it goes to load the groom.
1

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 

1 Comment

Wow, all three of these answers look like they would work. I guess I have a decision to make.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.