Для масового присвоєння значень моделі 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=
.
З рельсами 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
.