First ... caution: this railscast is very old. In this episode there may be syntactic things that were dated by new versions of rails.
Question 1
If you use the has_many through method, you must have an id column in the connection model because you are using a full-scale model . As Ryan mentions in the episode, you will choose this method if you need to track additional information. If you use the has_and_belongs_to_many method, you will not have an id column in your table.
If you want to receive a check in which you do not allow duplicates in your many-to-many association (ie Allow the pairing of element a with element b and again allow another entry of element a to element b), you can use a simple validates a row with scope:
validates_uniqueness_of :model_a_id, :scope => [:model_b_id]
Question 2
You can add indexes to your migrations with this code.
add_index :table_name, [ :join_a_id, :join_b_id ], :unique => true, :name => 'by_a_and_b'
This will be added to the change block below your create_table statement (but not in that create_table block). Check this question for more details: In the join table, what is the best workaround for missing a Rails complex key?
Question 3
I donโt quite understand what you want to do, but if you want to take some action every time a new record is inserted into the join model, I would use the active capture of the after_create record. It will look something like this.
class YourJoinModel < ActiveRecord::Base after_create :do_something def do_something puts "hello world" end end
This do_something function will be called every time a new record is created.
Question 4
Using the has_many method will give you access to additional attributes that you defined in this model on either side of the relationship. For example, if you have this setting:
class Factory < ActiveRecord::Base has_many :widgets, :through => :showcases end class Widget < ActiveRecord::Base has_many :factories, :through => :showcases end class Showcases < ActiveRecord::Base belongs_to :factory belongs_to :widget attr_accessiable :factory_id, :widget_id, :visible end
Could you say something like
widget = Widget.first shown = widget.showcases shown.first.visible
or
shown = widget.showcases.where( :visible=> true )
You can also contact another association:
shown.first.factory