Мне кажется, я вижу в чем проблема. Я уверен, что вы не можете сделать следующее:
# Triggers a database call
document_section = @document.document_sections.find_by_id(k)
И ожидать, что ActiveRecord сохранит связь для автосохранения. Вместо этого вы должны сохранять загруженные записи по отдельности. Что, конечно, не было бы атомным.
Я полагаю, что автосохранение работает так, как вы думаете, вы хотите сделать что-то вроде этого:
# untested...
@document.document_sections.collect { |s| s.id == k }.foo = "bar"
Обратите внимание, что здесь я на самом деле изменяю фиктивный параметр foo
в массиве вместо вызова find_by_id, который будет повторно запрашивать базу данных и возвращать новый объект.
Третий вариант, который у вас есть, состоит в том, что вы, конечно, можете делать то, что изначально планировали, но обрабатывать все транзакции самостоятельно или использовать вложенные транзакции и т. Д., Чтобы получить безопасные данные. Это было бы необходимо, если бы ваши данные были слишком большими для работы с массивами, поскольку автоматическое сохранение по своей природе запускает загрузку всех связанных данных в память.
Все зависит от вашего приложения.
Некоторые разъяснения по основной проблеме:
Если вы запускаете метод find_by_id
, вы просите ActiveRecord
вернуть вам новый набор объектов, соответствующих этому запросу. Тот факт, что вы выполнили этот метод из экземпляра (document_sections
), на самом деле является еще одним способом сказать:
DocumentSection.find_by_id(k)
Вызывать его из экземпляра объекта, я думаю, это просто некоторая синтаксическая привлекательность, которую рельсы добавляют в начало, но, на мой взгляд, это не имеет большого смысла; Я думаю, что это может быть удобно в некоторых приложениях, я не уверен.
С другой стороны, collect
- это метод Ruby Array, который предлагает способ «разрезать» массив с помощью блока. В основном модный цикл foreach. :) При непосредственном взаимодействии с массивом document_sections вы изменяете те же объекты, которые уже были загружены в содержащий объект (@document
), которые затем будут зафиксированы при save
со специальным флагом autosave
.
НТН! Рад, что ты вернулся и бежишь. :)