SitePoint Sponsor |
|
User Tag List
Results 1 to 6 of 6
-
Sep 8, 2008, 05:44 #1
- Join Date
- Nov 2003
- Location
- Sri Lanka
- Posts
- 156
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
inducting songs into a db using has_many :through
Hi,
I'm building an app where it reads a dir for files that end with .mp3 and insert them into a db along with the id3 tags in the files.
my problem is the relationship between the tables. i dont fully understand "has many through" associations yet. i come from a background of 5 years in PHP and i'm only just starting to learn ROR...i know a decent amount of Ruby though.
this is how i think the structure should be:
Code:class Album < ActiveRecord::Base has_one :artist, :through => tracks has_many :genres, :through => tracks has_many :tracks end class Artist < ActiveRecord::Base has_many :albums has_many :genres, :through => tracks has_many :tracks end class Genre < ActiveRecord::Base has_many :albums, :through => tracks has_many :artists, :through => tracks has_many :tracks end class Track < ActiveRecord::Base has_many :albums belongs_to :artist has_many :genres end
this is how i imagine my tables to look:
Code:# albums table create_table :albums do |t| t.string :title t.integer :track_id t.integer :artist_id end # artists table create_table :artists do |t| t.string :title t.integer :track_id end # genres table create_table :genres do |t| t.string :title t.integer :track_id end # tracks table create_table :tracks do |t| t.string :title t.integer :number t.integer :genre t.datetime :duration t.timestamps end
is this correct? any suggestions would be great too.
also, what if a track doesn't belong to an album, how would i go about sorting that out?
thanks.
-
Sep 8, 2008, 12:06 #2
- Join Date
- Jul 2007
- Posts
- 19
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
Has many through relationships are used when just a simple join table doesn't represent the entire relationship.
A basic many-to-many relationhip may be as follows:
users can be in many groups
groups can have many users
join table is users_groups, that simply maps users to multiple groups.
A more advanced relationship appropriate for has many through could be as follows:
magazines have many readers through subscriptions
readers are associated to magazines through subscriptions
Rather than just a simple magazines_readers join table, you would have a table called subscriptions which not only mapped magazines to readers, but also contained data such as subscription start and end date, price, etc.
To summarize, you use has_many :through when the relationship between two tables contains more data than simply that each record can have many of the other.
That being said, it is still ok (and probably the standard now) to use has_many through even if its just a simple join relationship, because it gives you the ability to create a third model with a name that makes sense in your business logic. A has_and_belongs_to_many won't have that third model.
-
Sep 9, 2008, 12:21 #3
- Join Date
- Nov 2003
- Location
- Sri Lanka
- Posts
- 156
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
jeffct, i agree with you.
i was going to use has_and_belongs_to_many but everybody else told me to use has_many through...almost as if they expect has_and_belongs_to_many to be deprecated in the future.
however, my question is will my model work? and is it efficient for what i've described?
thanks.
-
Sep 13, 2008, 09:14 #4
- Join Date
- Jun 2008
- Posts
- 31
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
I would put:
class Artist < ActiveRecord::Base
has_many :albums
end
class Album < ActiveRecord::Base
belongs_to :artist
has_many :tracks
belongs_to :genre
end
class Track < ActiveRecord::Base
belongs_to :album
end
class Genre < ActiveRecord::Base
has_many :albums
end
table artists doesn't have a foreign key, table albums has artist_id and genre_id, table tracks has album_id and genres don't have a foreign key
-
Sep 13, 2008, 14:56 #5
- Join Date
- Nov 2003
- Location
- Sri Lanka
- Posts
- 156
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
hey thanks for the suggestion
but that wont work because i would need to find tracks by genre so there must be a direct many-to-many relationship between tracks and genres.
also, an album can have many tracks and a track can have many albums.
for example, a track might appear in an artists regular album but it might also appear in that artsts "Greatest Hits" album. there are many instances like that so i want to be open to that option too.
thanks for taking the time to reply
-
Sep 14, 2008, 16:24 #6
- Join Date
- Jun 2008
- Posts
- 31
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
OK then make a new connector model for example AlbumTrackConnector
class AlbumTrackConnector < ActiveRecord::Base
belongs_to :album
belongs_to :track
end
And redefine Album and Track model
class Album < ActiveRecord::Base
has_many :album_track_connectors
has_many :tracks, :through => :album_track_connectors
end
class Track < ActiveRecord::Base
has_manu :album_track_connectors
has_many :albums, :through => :album_track_connectors
end
do the similar for tracks and genres
Bookmarks