dave miller
2005-Aug-23 16:08 UTC
ActiveRecord Question : Populating Extra Columns in Join Tables
Hey everyone, I''ve been tooling around with Rails for a little while now and I just came across my first question that I haven''t been able to find an answer to :). I''ve got two models, Playlist and Track, that describe my music library. Tracks contain the information about songs, and Playlists are composed of any number of Tracks (in addition to any information unique to a playlist, such as its name). So there''s also a playlists_tracks table that can join the two tables together. Nothing fancy. So to add a track to a playlist, I can do the following (minus any error checking)... track = Track.find(@params[''track''].to_i) playlist = Playlist.find(@params[''id''].to_i) track.playlists << playlist The code listed above will create a record in the playlists_tracks table, as desired. The only problem is that the playlists_tracks table contains more information than just the playlist_id column and the track_id column. For example, there''s an ''enabled'' column that indicates whether or not this track is enabled (ie: should be played) or not. And there may be more information added further on down the road... How can I populate the extra column(s) in the playlists_tracks table when creating a new record as shown above without resorting to manually writing SQL? Is it possible? Thanks for any help you can provide. dave
Rick Olson
2005-Aug-23 17:18 UTC
Re: ActiveRecord Question : Populating Extra Columns in Join Tables
On 8/23/05, dave miller <davidfmiller-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> Hey everyone, > > I''ve been tooling around with Rails for a little while now and I just > came across my first question that I haven''t been able to find an > answer to :). > > I''ve got two models, Playlist and Track, that describe my music > library. Tracks contain the information about songs, and Playlists are > composed of any number of Tracks (in addition to any information > unique to a playlist, such as its name). So there''s also a > playlists_tracks table that can join the two tables together. Nothing > fancy. > > So to add a track to a playlist, I can do the following (minus any > error checking)... > > track = Track.find(@params[''track''].to_i) > playlist = Playlist.find(@params[''id''].to_i) > track.playlists << playlist > > The code listed above will create a record in the playlists_tracks > table, as desired. The only problem is that the playlists_tracks table > contains more information than just the playlist_id column and the > track_id column. For example, there''s an ''enabled'' column that > indicates whether or not this track is enabled (ie: should be played) > or not. And there may be more information added further on down the > road... > > How can I populate the extra column(s) in the playlists_tracks table > when creating a new record as shown above without resorting to > manually writing SQL? Is it possible? > > Thanks for any help you can provide. > > daveLooking at the docs: http://rails.rubyonrails.com/classes/ActiveRecord/Associations/ClassMethods.html#M000430, you can use push_with_attributes. @developer.projects.push_with_attributes(@project, :started_at => Time.now) <% @developer.projects.each do |project| -%> <%= @developer.name %> started <%= project.title %> on <%= project.started_at %> <% end -%> Yes, it fills the object with the extra attribute automatically. It seems like this worked both ways: @project.started_at = Time.now @developer.projects << @project But, the docs don''t mention it. I can''t guarantee results from my flaky memory. A word of warning, Rails will have absolutely no clue what type those extra fields are. Since that join table is not a model, rails never grabs the table info, so just assumes every field is a string. If that third table needs more stuff (validations, callbacks, a primary key, etc), then it''s better off being its own model with a has_many relationship to the other two models. -- rick http://techno-weenie.net
Ken Kunz
2005-Aug-23 18:14 UTC
Re: ActiveRecord Question : Populating Extra Columns in Join Tables
> If that third table needs more stuff (validations, callbacks, a primary > key, etc), then it''s better off being its own model with a has_many > relationship to the other two models.Actually, wouldn''t it be a belongs_to relationship to the other two model classes? And the original two model classes would each have a has_many to the third one. Ken
Rick Olson
2005-Aug-23 19:14 UTC
Re: ActiveRecord Question : Populating Extra Columns in Join Tables
> Actually, wouldn''t it be a belongs_to relationship to the other two > model classes? And the original two model classes would each have a > has_many to the third one.Ah right you are. I had the associations backwards. -- rick http://techno-weenie.net
dave miller
2005-Aug-23 23:05 UTC
Re: ActiveRecord Question : Populating Extra Columns in Join Tables
On 8/23/05, Rick Olson <technoweenie-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> On 8/23/05, dave miller <davidfmiller-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: > > Hey everyone, > > > > I''ve been tooling around with Rails for a little while now and I just > > came across my first question that I haven''t been able to find an > > answer to :). > > > > I''ve got two models, Playlist and Track, that describe my music > > library. Tracks contain the information about songs, and Playlists are > > composed of any number of Tracks (in addition to any information > > unique to a playlist, such as its name). So there''s also a > > playlists_tracks table that can join the two tables together. Nothing > > fancy. > > > > So to add a track to a playlist, I can do the following (minus any > > error checking)... > > > > track = Track.find(@params[''track''].to_i) > > playlist = Playlist.find(@params[''id''].to_i) > > track.playlists << playlist > > > > The code listed above will create a record in the playlists_tracks > > table, as desired. The only problem is that the playlists_tracks table > > contains more information than just the playlist_id column and the > > track_id column. For example, there''s an ''enabled'' column that > > indicates whether or not this track is enabled (ie: should be played) > > or not. And there may be more information added further on down the > > road... > > > > How can I populate the extra column(s) in the playlists_tracks table > > when creating a new record as shown above without resorting to > > manually writing SQL? Is it possible? > > > > Thanks for any help you can provide. > > > > dave > > Looking at the docs: > http://rails.rubyonrails.com/classes/ActiveRecord/Associations/ClassMethods.html#M000430, > you can use push_with_attributes. > > @developer.projects.push_with_attributes(@project, :started_at => Time.now) > > <% @developer.projects.each do |project| -%> > <%= @developer.name %> started <%= project.title %> on <%= project.started_at %> > <% end -%> > > Yes, it fills the object with the extra attribute automatically. It > seems like this worked both ways: > > @project.started_at = Time.now > @developer.projects << @project > > But, the docs don''t mention it. I can''t guarantee results from my flaky memory. > > A word of warning, Rails will have absolutely no clue what type those > extra fields are. Since that join table is not a model, rails never > grabs the table info, so just assumes every field is a string. If > that third table needs more stuff (validations, callbacks, a primary > key, etc), then it''s better off being its own model with a has_many > relationship to the other two models. > > -- > rick > http://techno-weenie.net > _______________________________________________ > Rails mailing list > Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org > http://lists.rubyonrails.org/mailman/listinfo/rails >-- dave