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