Asp Forum
Home
|
Login
|
Register
|
Search
Forums
>
comp.lang.ruby
How to map this association
Wenhan Zhou
8/11/2008 3:35:00 PM
Hi, This is the scenario
A user can create videos and collect videos.
I was coding the creation side of the videos so I was using a belongs_to
and a has_many.
Then when I came to the part of collecting the videos, I am stumped with
how to implement the association.
Normally I would just use a table with user_id and video_id.
But in this case, this would conflict with my earlier code.
so the question is this: how do I implement an association for the
scenario belong.
A user can create multiple video that are shown on his profile page
(1 to Many)
user.rb :has_many :videos
video.rb :belongs_to :user
user table has a coloum called video_id
A user can also collect a video. This list is shown as videos favorited
by this user(Each video can also be favourite by many people)
(many to many)
user.rb : has_and_belongs_to_many :videos
video.rb :has_and_belongs_to_many :users
created a new table called user_video with user_id & video_id
Since the 2 associations are for exactly the same models,
what happens when I call @user.videos
will I
1) Get the list of videos created by this user
2) Get the list of videos collected by this user
3) the system goes bonkers :(
Is this the wrong way to implement this?
--
Posted via
http://www.ruby-...
.
2 Answers
Phill Davies
8/11/2008 8:04:00 PM
0
Hi,
I'm guessing this is a Rails question, in which case you should post
it to the rails list (
http://www.ruby-forum.c...
). Anyway, since
the question of ActiveRecord in ruby (sans rails) has been in the news
so much lately, I guess it couldn't hurt to answer this here.
If I understand the problem correctly, you have Users and Videos.
Videos have a creator (1 creator to many videos) as well as owners (many
owners to many videos). You were pretty close, except that the since 1
creator can have many videos you want the Video model to have a field
e.g. user_id (or creator_id), rather than your User model having a
video_id field.
Phill
Wenhan Zhou wrote:
> Hi, This is the scenario
>
> A user can create videos and collect videos.
>
> I was coding the creation side of the videos so I was using a belongs_to
> and a has_many.
>
> Then when I came to the part of collecting the videos, I am stumped with
> how to implement the association.
>
> Normally I would just use a table with user_id and video_id.
> But in this case, this would conflict with my earlier code.
>
> so the question is this: how do I implement an association for the
> scenario belong.
>
> A user can create multiple video that are shown on his profile page
> (1 to Many)
> user.rb :has_many :videos
> video.rb :belongs_to :user
> user table has a coloum called video_id
>
> A user can also collect a video. This list is shown as videos favorited
> by this user(Each video can also be favourite by many people)
> (many to many)
> user.rb : has_and_belongs_to_many :videos
> video.rb :has_and_belongs_to_many :users
> created a new table called user_video with user_id & video_id
>
> Since the 2 associations are for exactly the same models,
> what happens when I call @user.videos
> will I
> 1) Get the list of videos created by this user
> 2) Get the list of videos collected by this user
> 3) the system goes bonkers :(
>
> Is this the wrong way to implement this?
--
Posted via
http://www.ruby-...
.
Lake Denman
8/11/2008 8:59:00 PM
0
Hi Wenhan,
This is how I set up my association and I think it works well... I'm
using has_many through instead of has_and_belongs_to_many. I think that
using has_many through is now more widely accepted than it's
predecessor.
Anyways, on to the show. Here's what we have:
Models
User:
has_many :videos, :foreign_key=>'added_by' # in retrospect that might
not be the best name. You could try contributor_id, maybe.
has_many :video_collections
has_many :collected_videos, :through=>:video_collections,
:source=>:video # We have to specify a source since we aren't really
following the naming convention.
Video:
belongs_to :user, :foreign_key=>'added_by'
has_many :video_collections
has_many :collectors, :through=>:video_collections,:source=>:user
VideoCollection:
belongs_to :user
belongs_to :video
Next up, Simple Migrations for the Models!
Users
class CreateUsers < ActiveRecord::Migration
def self.up
create_table :users do |t|
t.string :name
t.timestamps
end
User.create!(:name=>"Lake")
end
def self.down
drop_table :users
end
end
Videos
class CreateVideos < ActiveRecord::Migration
def self.up
create_table :videos do |t|
t.string :title
t.integer :added_by
t.timestamps
end
Video.create!(:title=>"Gone With The Wind", :added_by=>1)
end
def self.down
drop_table :videos
end
end
Video Collections (rumor has it that you can pass :id=>false here, but I
forgot to do that when I generated this)
class CreateVideoCollections < ActiveRecord::Migration
def self.up
create_table :video_collections do |t|
t.integer :user_id
t.integer :video_id
t.timestamps
end
VideoCollection.create!(:user_id=>1, :video_id=>1)
end
def self.down
drop_table :video_collections
end
end
Okay, so we have our migrations setup and the next thing we cna do is
Migrate:
rake db:create:all;rake db:migrate
Then fire up the script/console in your rails_root directory: ruby
script/console
Let's see what happens (ps. We already created some rows in the
migrations):
#Make sure all our entities are there:
>> User.find(1)
=> #<User id: 1, name: "Lake", created_at: "2008-08-11 20:53:24",
updated_at: "2008-08-11 20:53:24">
>> Video.find(1)
=> #<Video id: 1, title: "Gone With The Wind", added_by: 1, created_at:
"2008-08-11 20:53:24", updated_at: "2008-08-11 20:53:24">
>> VideoCollection.find(1)
=> #<VideoCollection id: 1, user_id: 1, video_id: 1, created_at:
"2008-08-11 20:53:24", updated_at: "2008-08-11 20:53:24">
# Check videos associated with users
>> User.find(1).videos
=> [#<Video id: 1, title: "Gone With The Wind", added_by: 1, created_at:
"2008-08-11 20:53:24", updated_at: "2008-08-11 20:53:24">]
# Check user associated with video
>> Video.find(1).user
=> #<User id: 1, name: "Lake", created_at: "2008-08-11 20:53:24",
updated_at: "2008-08-11 20:53:24">
# Check collected videos associated with user
>> User.find(1).collected_videos
=> [#<Video id: 1, title: "Gone With The Wind", added_by: 1, created_at:
"2008-08-11 20:53:24", updated_at: "2008-08-11 20:53:24">]
# Check collector associated with video
>> Video.find(1).collectors
=> [#<User id: 1, name: "Lake", created_at: "2008-08-11 20:53:24",
updated_at: "2008-08-11 20:53:24">]
# Let's make sure we really are getting different associations since
it's only fairly proven.
# Let's create a new video
>> Video.create!(:title=>'Gone With The Wind', :added_by=>2)
=> #<Video id: 2, title: "Gone With The Wind", added_by: 2, created_at:
"2008-08-11 20:58:43", updated_at: "2008-08-11 20:58:43">
# Let's create a new video collection for user 1 and video 2
>> VideoCollection.create(:user_id=>1, :video_id=>2)
=> #<VideoCollection id: 2, user_id: 1, video_id: 2, created_at:
"2008-08-11 20:59:26", updated_at: "2008-08-11 20:59:26">
# Now let's ask the user for it's collected videos
>> User.find(1).collected_videos
=> [#<Video id: 1, title: "Gone With The Wind", added_by: 1, created_at:
"2008-08-11 20:53:24", updated_at: "2008-08-11 20:53:24">, #<Video id:
2, title: "Gone With The Wind", added_by: 2, created_at: "2008-08-11
20:58:43", updated_at: "2008-08-11 20:58:43">]
# And now for User 1's videos that he added
>> User.find(1).videos
=> [#<Video id: 1, title: "Gone With The Wind", added_by: 1, created_at:
"2008-08-11 20:53:24", updated_at: "2008-08-11 20:53:24">]
Hope that helps some.
Lake
Wenhan Zhou wrote:
> Hi, This is the scenario
>
> A user can create videos and collect videos.
>
> I was coding the creation side of the videos so I was using a belongs_to
> and a has_many.
>
> Then when I came to the part of collecting the videos, I am stumped with
> how to implement the association.
>
> Normally I would just use a table with user_id and video_id.
> But in this case, this would conflict with my earlier code.
>
> so the question is this: how do I implement an association for the
> scenario belong.
>
> A user can create multiple video that are shown on his profile page
> (1 to Many)
> user.rb :has_many :videos
> video.rb :belongs_to :user
> user table has a coloum called video_id
>
> A user can also collect a video. This list is shown as videos favorited
> by this user(Each video can also be favourite by many people)
> (many to many)
> user.rb : has_and_belongs_to_many :videos
> video.rb :has_and_belongs_to_many :users
> created a new table called user_video with user_id & video_id
>
> Since the 2 associations are for exactly the same models,
> what happens when I call @user.videos
> will I
> 1) Get the list of videos created by this user
> 2) Get the list of videos collected by this user
> 3) the system goes bonkers :(
>
> Is this the wrong way to implement this?
--
Posted via
http://www.ruby-...
.
Servizio di avviso nuovi messaggi
Ricevi direttamente nella tua mail i nuovi messaggi per
How to map this association
Inserendo la tua e-mail nella casella sotto, riceverai un avviso tramite posta elettronica ogni volta che il motore di ricerca troverà un nuovo messaggio per te
Il servizio è completamente GRATUITO!
x
Login to ForumsZone
Login with Google
Login with E-Mail & Password