How to save extra fields in Rails using has_and_belongs_to_many
I have the following structure in my rails application:
class Movie < ActiveRecord::Base has_and_belongs_to_many :celebs, :join_table => "movies_celebs" end class Celeb < ActiveRecord::Base has_and_belongs_to_many :movies, :join_table => "movies_celebs" end class MovieCeleb < ActiveRecord::Base belong_to :movie belong_to :celeb end
Now MovieCeleb has 2 extra fields CastName(string), CastType('Actor/Director). When I save Movie i create celebs also and fill celebs into celebs relation and it save movies_celebs automatically into database. But how can i pass the CastName and CastType to save also.
Thanks in advance.
Note the following is for Rails v2
script/generate model Movie id:primary_key name:string script/generate model Actor id:primary_key movie_id:integer celeb_id:integer cast_name:string cast_type:string script/generate model Celeb id:primary_key name:string model/movie.rb class Movie < ActiveRecord::Base has_many :actors has_many :celebs, :through => :actors end model/celeb.rb class Celeb < ActiveRecord::Base has_many :actors has_many :movies, :through => :actors end model/actor.rb class Actor < ActiveRecord::Base belongs_to :movie belongs_to :celeb end
Test the associations with the ruby rails console in the application folder
>script/console >m = Movie.new >m.name = "Do Androids Dream Of Electric Sheep" >m.methods.sort #this will list the available methods #Look for the methods 'actors' and 'celebs' - these #are the accessor methods built from the provided models >m.actors #lists the actors - this will be empty atm >c = Celeb.new >c.name = "Harrison Ford" >m.celebs.push(c) #push Harrison Ford into the celebs for Blade Runner >m.actors #Will be empty atm because the movie hasnt been saved yet >m.save #should now save the Movie, Actor and Celeb rows to relevant tables >m.actors #Will now contain the association for #Movie(id : 1, name : "Do Androids..") - Actor(id : 1, movie_id : 1, celeb_id : 1) - #Celeb(id : 1, name : "Harrision Ford") >m = Movie.new #make a new movie >m.name = "Star Wars" >m.celebs.push(c) #associated the existing celeb with it >m.save >movies = Movie.all #should have the two movies saved now >actors = Actor.all #should have 2 associations >this_actor = Actor.first >this_actor.cast_type = "ACTOR" >this_actor.save
Then you'll probably want to check out Ryan Bates' Railcasts http://railscasts.com #47 (Two Many-to-Many), and #73, #74, #75 (Complex forms parts 1-3).
There's an updated version of the many-to-many form code on the webpage for #75.
You should use has_many :through instead of has_and_belongs_to_many if you need validations, callbacks, or extra attributes on the join model.