I have what I think is a fairly complex modeling problem for you guys.
So I have a user class. There are three link type classes: picture,
video, and story. A user can vote, bookmark, and add any of those
types. Essentially I want to be able to say:
user.stories and get the stories the user has uploaded
user.votes.stories and get the votes that are stories
user.votes.videos and get the votes that are videos
user.bookmarks.videos and get the bookmarks for the videos
So these are essentially join tables, but I can’t seem to get them to
go properly, have tried polymorphism and has_many_polymorphs, limited
success, limited knowledge.
Now I also want to be able to go the other way:
story.votes
story.user
story.bookmarks
I will be seriously impressed if anyone can tackle this
Jables wrote:
| I have what I think is a fairly complex modeling problem for you guys.
|
| So I have a user class. There are three link type classes: picture,
| video, and story. A user can vote, bookmark, and add any of those
| types. Essentially I want to be able to say:
| user.stories and get the stories the user has uploaded
| user.votes.stories and get the votes that are stories
| user.votes.videos and get the votes that are videos
| user.bookmarks.videos and get the bookmarks for the videos
|
| So these are essentially join tables, but I can’t seem to get them to
| go properly, have tried polymorphism and has_many_polymorphs, limited
| success, limited knowledge.
|
| Now I also want to be able to go the other way:
|
| story.votes
| story.user
| story.bookmarks
|
| I will be seriously impressed if anyone can tackle this
|
| Thanks for the help,
| JB
class Story < ActiveRecord::Base
~ has_many :votes
~ belongs_to :user
~ end
end
class User < ActiveRecord::Base
~ has_many :stories
~ has_many :votes
~ has_many :stories_voted_on, :through => :votes, :source => :story
end
~ - You know you’ve been hacking too long when…
…your children do something they shouldn’t do, you tell them to stop,
they
do it just once more anyway, so you think “Well, they prefetched the
instruction and are executing it in the delay slot.”
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.8 (MingW32)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org
So these are essentially join tables, but I can’t seem to get them to
go properly, have tried polymorphism and has_many_polymorphs, limited
success, limited knowledge.
Now I also want to be able to go the other way:
story.votes
story.user
story.bookmarks
Well a user has_many :videos (and the story :belongs_to :user) which
takes care of who uploaded what
A user has_many votes, has_many bookmarks, again that’s not the
complicated bit. From now on lets just think about bookmarks since
it’s basically the same think at this point.
The bookmark model could belong_to :user, and belongs_to :
bookmark_content, :polymorphic => true
Over on video, we can say video has_many :bookmarks, :as =>
bookmark_content
This takes care of video.bookmarks.
The only remaining bit is user.bookmarks.videos
off the top of my head you could solve it like this: replace the
has_many :bookmarks on user with
has_many :bookmarks do
def videos
Video.find :all, :joins => :bookmarks, :conditions =>
[‘bookmarks.user_id = ?’, proxy_owner.id]
end
end
you can define bookmarks.stories, bookmarks.pictures in a similar way
Fred’s suggestion is an excellent one: defining additional hooks right
off the has_many line. I’ve used that. In my case, I had: “user
has_many profiles” and then defined a “default” as an accessor off of
that (using almost exactly the code Fred posted). Then, I could do:
User.find(:first).profiles.default # => the profile flagged as
“default” for that user.
You should be able to do exactly the same thing. So kudos to Fred.