I didn''t find exactly an answer on this one, so I''d like to get a clarification from folks who live & breathe HABTM. class foo has_and_belongs_to_many :bars end class bar has_and_belongs_to_many :foos end (and yes, I have a bars_foos table in my db) def test_habtm bar = Bar.new foo = Foo.new foo.bars<<bar assert !foo.bars.empty? assert !bar.foos.empty? end My first assert passes just fine. But the 2nd fails. Am I wrong on the concepts of HABTM? Shouldn''t the << operator add to the join table and therefore the next find from either object return a non-empty array? thx, --dwf -- Posted via http://www.ruby-forum.com/.
Josh Susser
2006-Aug-09 00:02 UTC
[Rails] Re: HABTM and getting to arrays from either direction
DWFrank wrote:> I didn''t find exactly an answer on this one, so I''d like to get a > clarification from folks who live & breathe HABTM. > > class foo > has_and_belongs_to_many :bars > end > > class bar > has_and_belongs_to_many :foos > end > > (and yes, I have a bars_foos table in my db) > > def test_habtm > bar = Bar.new > foo = Foo.new > > foo.bars<<bar > assert !foo.bars.empty? > assert !bar.foos.empty? > end > > My first assert passes just fine. But the 2nd fails. Am I wrong on the > concepts of HABTM? Shouldn''t the << operator add to the join table and > therefore the next find from either object return a non-empty array?<< acts different depending on whether the record has been saved or not. If it is not a new record (has already been saved), the join table will be updated when << is sent. If it hasn''t yet been saved, it has no id to put in the join table, so it just saves the associated object in the bars collection and waits to create the entry in the join table when it gets saved. Try saving the objects and see what happens then. -- Josh Susser http://blog.hasmanythrough.com/ -- Posted via http://www.ruby-forum.com/.
DWFrank
2006-Aug-09 19:32 UTC
[Rails] Re: HABTM and getting to arrays from either direction
Figured out my problem. Validation was preventing the save of a foo within the test code. I did the smart thing and made EXACTLY the code above and it bar.foos.empty? is true. What I did find odd was that bar.foos.include?(foo) doesn''t work. I''m sure this has something to do with ActiveRecord arrays. But I''m now using bar.foos.find(foo.id) and I''m happy. thx, --dwf -- Posted via http://www.ruby-forum.com/.
Mark Reginald James
2006-Aug-10 05:54 UTC
[Rails] Re: HABTM and getting to arrays from either direction
DWFrank wrote:> I didn''t find exactly an answer on this one, so I''d like to get a > clarification from folks who live & breathe HABTM. > > class foo > has_and_belongs_to_many :bars > end > > class bar > has_and_belongs_to_many :foos > end > > (and yes, I have a bars_foos table in my db) > > def test_habtm > bar = Bar.new > foo = Foo.new > > foo.bars<<bar > assert !foo.bars.empty? > assert !bar.foos.empty? > end > > My first assert passes just fine. But the 2nd fails. Am I wrong on the > concepts of HABTM? Shouldn''t the << operator add to the join table and > therefore the next find from either object return a non-empty array?Not an HABTM expert but... The foos.bars collection is not empty because it''s an in-memory array to which you''ve explicitly appended bar. The bar.foos collection won''t include foo until foo is saved (also saving bar and creating the join table entry). I suppose Rails could be written to automatically keep the reverse collection in sync, both prior to and through saves, but the code would be a bit tricky. -- We develop, watch us RoR, in numbers too big to ignore.