Same has_many and has_one?

I think I’ve just thoroughly confused myself at this point. I have a
class that has a has_many and has_one relationship that use the same
object.

Here is an example:

class Person < ActiveRecord::Base
has_many :hobbies
has_one :favorite_hobby, :class_name => “Hobby”
end

class Hobby < ActiveRecord::Base
belongs_to :person
belongs_to :person, :foreign_key => “favorite_hobby_id”
end

Of course, this doesn’t work. Any ideas what I need to change to get
this to work properly?

Thanks.

The B. wrote:

I think I’ve just thoroughly confused myself at this point. I have a
class that has a has_many and has_one relationship that use the same
object.

Here is an example:

class Person < ActiveRecord::Base
has_many :hobbies
has_one :favorite_hobby, :class_name => “Hobby”
end

class Hobby < ActiveRecord::Base
belongs_to :person
belongs_to :person, :foreign_key => “favorite_hobby_id”
end

Of course, this doesn’t work. Any ideas what I need to change to get
this to work properly?

Thanks.

I think you should be using habtm for the hobbies (two people can enjoy
the same hobby, right?) and an additional belongs_to for the favorite.
This may seem counterintuitive, but remember that belongs_to is used on
the table with the foreign key field (which in this case is
people.favorite_hobby_id). So:

class Person
habtm :hobbies
belongs_to :favorite_hobby, :class_name => ‘Hobby’
end

class Hobby
habtm :people

reverse association probably unnecessary for favorite_hobby

end

Best,

Marnen Laibow-Koser
http://www.marnen.org
[email protected]

Hrm - maybe I should just quote my actual code rather than the example.
Actually, technically, no - the “hobbies” are NOT shared between people.
So two people can’t share the same hobby.

Each Person has their own list of hobbies, and one of those is their
“favorite” and I dont want to have some “favorite” boolean. My actual
code has nothing to do with people and hobbies, this was just a (poor)
example.

Thanks for the help!

Marnen Laibow-Koser wrote:

The B. wrote:

I think I’ve just thoroughly confused myself at this point. I have a
class that has a has_many and has_one relationship that use the same
object.

Here is an example:

class Person < ActiveRecord::Base
has_many :hobbies
has_one :favorite_hobby, :class_name => “Hobby”
end

class Hobby < ActiveRecord::Base
belongs_to :person
belongs_to :person, :foreign_key => “favorite_hobby_id”
end

Of course, this doesn’t work. Any ideas what I need to change to get
this to work properly?

Thanks.

I think you should be using habtm for the hobbies (two people can enjoy
the same hobby, right?) and an additional belongs_to for the favorite.
This may seem counterintuitive, but remember that belongs_to is used on
the table with the foreign key field (which in this case is
people.favorite_hobby_id). So:

class Person
habtm :hobbies
belongs_to :favorite_hobby, :class_name => ‘Hobby’
end

class Hobby
habtm :people

reverse association probably unnecessary for favorite_hobby

end

Best,

Marnen Laibow-Koser
http://www.marnen.org
[email protected]

Rick wrote:
[…]

I’m new so I don’t have the full answer, but without the favorite
boolean,
behind the scenes I think a table of “HobbyFavorite” would be needed
that
has person_id and hobby_id, unless I’m missing something.

Since there would be a 1:1 association between Person and HobbyFavorite,
that would actually be functionally equivalent to just having a
hobby_favorite_id in Person.

Best,

Marnen Laibow-Koser
http://www.marnen.org
[email protected]

Marnen Laibow-Koser wrote:

Rick wrote:
[…]

I’m new so I don’t have the full answer, but without the favorite
boolean,
behind the scenes I think a table of “HobbyFavorite” would be needed
that
has person_id and hobby_id, unless I’m missing something.

Since there would be a 1:1 association between Person and HobbyFavorite,
that would actually be functionally equivalent to just having a
hobby_favorite_id in Person.

That is exactly how the database looks. Instead of people and hobbies,
my code actually uses Users and Characters. The People/Hobby was just
another example. Each user can have any number of characters, but only
one character is marked as the “selected character”.

The users table has a selected_character_id, and the characters table
has a user_id.

Thanks.

The B. wrote:
[…]

That is exactly how the database looks. Instead of people and hobbies,
my code actually uses Users and Characters. The People/Hobby was just
another example. Each user can have any number of characters, but only
one character is marked as the “selected character”.

The users table has a selected_character_id, and the characters table
has a user_id.

Thanks.

OK…then how about

class User
has_many :characters
belongs_to :selected_character, :class_name => ‘Character’
end

class Character
belongs_to :user
end

?

Best,

Marnen Laibow-Koser
http://www.marnen.org
[email protected]

On Thu, Jul 16, 2009 at 3:57 PM, The B.
<[email protected]

wrote:

Hrm - maybe I should just quote my actual code rather than the example.
Actually, technically, no - the “hobbies” are NOT shared between people.
So two people can’t share the same hobby.

Each Person has their own list of hobbies, and one of those is their
“favorite” and I dont want to have some “favorite” boolean. My actual
code has nothing to do with people and hobbies, this was just a (poor)
example.

I’m new so I don’t have the full answer, but without the favorite
boolean,
behind the scenes I think a table of “HobbyFavorite” would be needed
that
has person_id and hobby_id, unless I’m missing something.

So it sounds like you need two “has_one” relationships defined?

both Person and Hobby would have:
has_one: favorite_hobby

You then could have a FavoriteHobby model object with
belongs_to: person
belongs_to: hobby

I’m not 100% this would work or is a good idea, but nobody else has
suggested anything yet, so I’m trying to learn in the process. Take any
of
the above with a HUGE chunk of salt:)

OK…then how about

class User
has_many :characters
belongs_to :selected_character, :class_name => ‘Character’
end

class Character
belongs_to :user
end

That did it! I have no idea why my brain tends to reverse the belongs
and has relationships sometimes. Thanks a lot for your help.

The B. wrote:
[…]

That did it! I have no idea why my brain tends to reverse the belongs
and has relationships sometimes.

Well, in this case, the selected_character relationship is backwards
from what it “should” be. I wouldn’t have figured that out immediately
either. :slight_smile:

Thanks a lot for your help.

You’re welcome.

Best,

Marnen Laibow-Koser
http://www.marnen.org
[email protected]