Search code examples
rubyactiverecordjruby

How do you create many-to-many class instance relationships in JRuby w/ActiveRecord?


I have this basic setup:

class Foo < ActiveRecord::Base
  self.primary_key = 'foo_id'
  has_and_belongs_to_many :bars
end

class Bar < ActiveRecord::Base
  self.primary_key = :bar_id
  has_and_belongs_to_many :foos
end

Now I can see all the bars associated with foos using Foo.first.bars or Bar.first.foos and this works as expected.

Where I'm stumped is how to do something like this:

foo_rows = Foo.all
=> (all those rows)
bar_rows = Bar.all
=> (all those rows)
foo_rows.first.bars.find { |bar| bar.bar_id == 1 }.some_col
=> "The value from the database"
bar_rows.find { |bar| bar.bar_id == 1 }.some_col = 'a new value'
=> "a new value"
foo_rows.first.bars.find { |bar| bar.bar_id == 1 }.some_col
=> "a new value"

But instead that last line says "The value from the database"

How do I achieve the desired behaviour?


Solution

  • Your bar_rows and foo_rows.first.bars are arrays with different objects in memory. Just because the id attribute of one of their elements is equal, it doesn't mean they're the same objects:

    bar_rows.find { |bar| bar.bar_id == 1 }.object_id
    # => 40057500
    foo_rows.first.bars.find { |bar| bar.bar_id == 1 }.object_id
    # => 40057123
    

    You are changing attribute of one of these objects, there is no reason that the attribute of the second object should be changed.

    As for the JRuby part, it does not matter -- MRI would behave the same.