Для массового присвоения значений модели ActiveRecord без сохранения используйте методы assign_attributes
или attributes=
.Эти методы доступны в Rails 3 и новее.Тем не менее, есть небольшие различия и связанные с версией ошибки, о которых следует знать.
Оба метода следуют этому использованию:
@user.assign_attributes{ model: "Sierra", year: "2012", looks: "Sexy" }
@user.attributes = { model: "Sierra", year: "2012", looks: "Sexy" }
Обратите внимание, что ни один из методов не будет выполнять проверки или выполнять обратные вызовы;обратные вызовы и проверка будут происходить при вызове save
.
Rails 3
attributes=
немного отличается от assign_attributes
в Rails 3. attributes=
проверит, что аргумент передан емуявляется хешем и сразу возвращается, если нет;assign_attributes
не имеет такой проверки хэша.См. API-интерфейс назначения атрибутов ActiveRecord для attributes=
.
Следующий недействительный код завершится с ошибкой, просто вернувшись без установки атрибутов:
@user.attributes = [ { model: "Sierra" }, { year: "2012" }, { looks: "Sexy" } ]
attributes=
будет вести себя тихо, как если бы назначения были выполнены успешно, тогда как на самом деле это не так.
Этот недействительный код вызовет исключение, когда assign_attributes
попытается преобразовать в строку ключи хеш-функции включающего массива:
@user.assign_attributes([ { model: "Sierra" }, { year: "2012" }, { looks: "Sexy" } ])
assign_attributes
вызовет исключение NoMethodError
для stringify_keys
, что указывает на то, что первый аргумент не является хэшем.Само исключение не очень информативно в отношении фактической причины, но тот факт, что исключение действительно имеет место, очень важно.
Единственное различие между этими случаями - это метод, используемый для массового присвоения:attributes=
тихо завершается успешно, а assign_attributes
вызывает исключение, информирующее о том, что произошла ошибка.
Эти примеры могут показаться надуманными и в некоторой степени, но этот тип ошибки может легко возникнуть при преобразованииданные из API, или даже просто используя серию преобразования данных и забывая Hash[]
результаты окончательного .map
.Оставьте код на 50 строк выше и удалите 3 функции из вашего назначения атрибутов, и вы получите рецепт ошибки.
Урок с Rails 3 таков: всегда использование assign_attributes
вместо attributes=
.
Rails 4
В Rails 4 attributes=
- это просто псевдоним assign_attributes
.См. API-интерфейс назначения атрибутов ActiveRecord для attributes=
.
В Rails 4 любой метод может использоваться взаимозаменяемо.Неспособность передать хэш в качестве первого аргумента приведет к очень полезному исключению: ArgumentError: When assigning attributes, you must pass a hash as an argument.
Проверки
Если вы предварительно выполняете проверку назначений для save
, выможет быть интересно проверить перед сохранением.Для этого вы можете использовать методы valid?
и invalid?
.Оба возвращают логические значения.valid?
возвращает true, если несохраненная модель прошла все проверки, или false, если нет.invalid?
- это просто обратное значение valid?
valid?
можно использовать следующим образом:
@user.assign_attributes{ model: "Sierra", year: "2012", looks: "Sexy" }.valid?
Это даст вам возможность обрабатывать любые вопросы проверки до вызоваsave
.