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?
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.