Thanks!!
Nice! I was about to call it a day but this popped. Model naming is really tricky.
This came just in time. *Thanks* for not using the P-word. I always wondered if I was doing it wrong when I ran across errors. Will you go deeper... do you call it differently? Category.products still works? Eager loading still works?
Ryan, silly question, but does it matter at all if you use 'category_name' or :category_name? I see that a lot in Rails, some people use symbols, some people use strings, does it make any difference?
Another nice naming convention I've learned is GroupAssignment or CategoryAssignment. Thanks to Chris McGrath for that one.
Andreas, it doesn't really matter. The difference is that if the symbol is already used inside the app, using a symbol version will only leave you with one object in ObjectSpace while using a string will instantiate multiple objects:
irb(main):001:0> :category.object_id
=> 158498
irb(main):002:0> :category.object_id
=> 158498
irb(main):003:0> "category".object_id
=> 265090
irb(main):004:0> "category".object_id
=> 255990
Great railscast Ryan! Can you do one on has-many :through sometime? Thanks!
@Matt and David, I'm planning to do an episode entirely on has_many :through in the near future. In the meantime, @category.products will work and eager loading also works.
@Andreas, normally it doesn't make a difference which one you choose in Rails. However, the naming of associations is an exception. IIRC using strings here will cause problems - stick with symbols as shown in all the examples.
Congrats sir ! Great tutorial. i've been checkin some of them lately and gosh, it's crystal clear. perfect timing, nice timeline, handy topics, everything's just great. Keep on the good work and bravo again for all that knowledge you share with others.
Thanks Ryan! Your railscast blog continues to be a great help!
Hey great job Ryan this is super helpful. You helped me out on RailsForum and mention self-referencing many-to-many association. Is there a way I could get more help on that somehow (this doesn't seem like the appropriate place)? Perhaps email? or a good link?
@Jack, it's probably best to keep all detailed questions on the forums (which you are already doing, I'm just replying for the benefit of others).
Thanks for the association rails cast Ryan, you are my hero ;)
I just found your podcast from iTunes tonight and watched this episode, great stuff! Thank you!
Hey thanks for all the great screencasts, they are so so cool.
There's just one itch I have.
I've actually never used the has_and_belongs_to_many relationship for an app because when I started railing the REST and the has_many through technique was all the buzz.
However in one of your previous screencasts you had a very interesting method for a habtm relationships
collection_singular_ids=
which allowed you to update all the associated records in the join table by passing in a collection of new ids, it seemed that all the deletion of records that weren't in this new list were automatically done for you, if this is what is happening its very useful and I was wondering if the has_many through technique has a similar method?
Hi Ryan, I normally add a composite primary key to the habtm join table like this:
add_index :categorizations, [:product_id, :category_id], :primary => true
... and foreign key associations. Is there any reason not to? Or did you omit it to keep it simple?
@Joshua, the "category_ids=" method is one of the few reasons you may want to stick with has_and_belongs_to_many since has_many :throug doesn't have an equivilant. Of course you can still make your own if you're using has_many :through.
That said, many times the join table has extra information in it if you're using has_many :through. In that case you wouldn't want the interface to be simple checkboxes as shown in the earlier episode. You would need some way to manage the extra data in the join.
@Zubin, thanks for the suggestion. I didn't have any reason for omiting the composite primary key and probably should have included it. I usually only add keys and indexes when they become needed, but I think a HABTM join table is a good case where it's always needed.
@Ryan: I think a Railscast on :has_many :through with polymorphic associations would be really nice. I find lots of documentation on :has_many :through, and on polymorphism. But, hardly anything with them together. Also, if you do this, could you please make sure to go through the controller workflow (ie. what gets created and when). Again, this is an area that is almost never mentioned. The focus is almost always on the model. Also, could the has_many_polymorphs plugin be the answer?
so simple and clear, thanks!
by the way, Ryan, how do you toggle words so quickly in textmate?
for example when you was printing drop_table 'categories_products' in the migration.
there was no hotkey displayed :).
The escape key is what I used. It will look at the rest of the document and do some basic auto-completion.
A railscast that goes into more detail on has_many :through and polymorphic associations would be greatly appreciated.
after change to use has_many :through,it doesn't auto add the "product_ids" and "product_ids=" methods.
Then how to update the association ?
@RainChen, right, this is one reason you may want to stick with habtm. Some methods like "product_ids=" are not available so you'll have to create them manually if you need them.
Normally, to update the association you either create or update the join model itself. Such as "categoirzation.new" or "categorization.update_attributes". You can also use the "<<" method to create the join. See this for details:
http://blog.hasmanythrough.com/2006/8/19/magic-join-model-creation
<< is for adding.
How about removing the association?
When calling @product.categorizations.delete, nothing happened.
if calling @production.categorizations.clear
it gave a sql error some thing like " DELETE FROM categories_products WHERE `id` = NULL".(Because I use the legacy habtm table without autoincrement id )
so how to deal with this case?
Every model needs an auto-incrementing id column in Rails, so I recommend remaking a "categorizations" table and not trying to use the legacy categories_products table.
So it seems not so easy to change to use has_many :through.
How about the has_many_polymorphs plugin?
It is said that it could saves lives ^0^
I was wondering if anybody could tell me the best way to avoid duplicates with a has many through relationship. I basically want a pair of ids to be unique in the database...
thanks in advance
@jeff, you can avoid duplicates by using the validates_uniqueness_of method. You'll likely need to use the :scope option to include the other columns.
You said that eager loading works. What's the correct protocol for eager loading with a has_many :through relationship?
@Ryan Long, eager loading should work with has_many :through as well without any differences. It just does a mutli-table join.
thanks for the code I just found your podcast from iTunes tonight and watched this episode, great stuff! Thank you again!
Nice movie. Very helpful.
Do you intend t oupdate this for the current version? Would it be something like:
def self.up
create_table 'categories_products', :id => false do |t|
t.belongs_to :category
t.belongs_to :product
end
end
What the heck is kino trying to say?
thanks a lot!
@ryan:
Any chance you can do a screencast repeating #17 with the has_many :through and incorporating some additional field storage?


