После некоторого возни, похоже, что это немного сложнее, чем это.
Мое возни было так:
- Я создал пару моделей, Родитель
и ребенок с
has_many
отношения в одноразовых рельсах
приложение.
- Я открыл
script/console
и
тыкал вокруг.
Я создал нового родителя с ребенком и сохранил их
>> p = Parent.new;p.children << Child.new(:foo=>'bar');p.save
=> true
Смотри, ребенок в БД и его можно найти by_foo
>> p.children.find_by_foo('bar')
=> #<Child id: 1, foo: "bar", parent_id: 1, created_at: "2009-12-14 22:08:05", updated_at: "2009-12-14 22:08:05">
Я добавил еще одного ребенка в коллекцию, он отображается в p.children
, но не в методах коллекции, которые попадают в базу данных.
>> p.children << Child.new(:foo=>'bar')
=> [#<Child id: 1, foo: "bar", parent_id: 1, created_at: "2009-12-14 22:08:05", updated_at: "2009-12-14 22:08:05">, #<Child id: 2, foo: "bar", parent_id: 1, created_at: "2009-12-14 22:08:25", updated_at: "2009-12-14 22:08:25">]
>> p.children.find_by_foo('bar')
=> #<Child id: 1, foo: "bar", parent_id: 1, created_at: "2009-12-14 22:08:05", updated_at: "2009-12-14 22:08:05">
Я меняю ребенка, который находится в БД.
>> p.children[0].foo = 'baz'
=> "baz"
Когда я ищу его, он дает мне версию БД.
>> p.children.find_by_foo('bar')
=> #<Child id: 1, foo: "bar", parent_id: 1, created_at: "2009-12-14 22:08:05", updated_at: "2009-12-14 22:08:05">
Но местная коллекция не изменилась.
>> p.children
=> [#<Child id: 1, foo: "baz", parent_id: 1, created_at: "2009-12-14 22:08:05", updated_at: "2009-12-14 22:08:05">, #<Child id: 2, foo: "bar", parent_id: 1, created_at: "2009-12-14 22:08:25", updated_at: "2009-12-14 22:08:25">]
Так что, если вы снова сохраните p, изменения будут переданы.
Если вы хотите получить все локальные объекты ассоциации, включая те, которые были изменены, вы не можете использовать искатели ActiveRecord, потому что они попадают в базу данных, вместо этого используйте методы массива, как вы делали выше. Тем не менее, использование find_all
или select
будет проще для понимания
parent.children.select{|c| c.attr == 'foo'}