Відмінності між .build, .create і .create! і коли їх слід використовувати?


167

Тож я бачив людей, які використовують .build, .create і .create! всередині їхніх контролерів все більше і більше останнім часом. У чому відмінність від просто використання .new та passig об'єкта param'd і потім .save? Чи є плюси і мінуси? Чи використовує ці інші методи переваги?

Відповіді:


233

Є кілька відмінностей, але вони не великі:

  1. .createеквівалентний .newнаступному .save. Це просто більш лаконічно.
  2. .create!еквівалентний .newнаступному .save!(видає помилку, якщо збереження не вдається). Це також просто трохи коротше
  3. Я думаю, що .buildце переважно псевдонім для .new. Він працює в одну сторону в Rails 3 і інший в Rails <3.x

Найважливіша частина, однак, полягає в тому, що ці методи можна викликати через асоціацію ( has_manyтощо), щоб автоматично зв’язати дві моделі.


1
Я вибрав цю найбільш правильну відповідь через згадку про можливість пов’язати пов'язані з ними моделі - це цікава та важлива різниця, яку я думаю над використанням .new та .save. Що вимагає трохи додаткової роботи. Дякую.
Тім Найт

11
Незначне уточнення на 3 - build робить трохи більше, ніж просто нове - воно також встановлює зв'язок асоціації.
Два біт-гангстера

116
Збірка відрізняється від нової. Але різниця полягає не в тому, що він встановлює зв'язок асоціації (Нове робить це теж для нового екземпляра). Різниця полягає в тому, що Build заповнює абонента новим екземпляром, але New це не робить. Так, наприклад: Wall.posts.new дає вам нову публікацію, пов’язану з вашою стіною, але Wall.posts все ще порожній після цього дзвінка. Wall.posts.build дає вам нову публікацію, пов’язану з вашою стіною, і тепер ваші стінки Wall.posts містять одну посаду.
Амін Аріана

3
Це не просто псевдонім зараз, без особливих функціональних можливостей?
Габріеле Cirulli

14
У Rails 4 я щойно перевірив консоль. wall.posts.new та wall.posts.build обидва заселяють стіновий об’єкт точно однаковим чином. Засоби за wall.posts.new, wall.posts не порожні, як стверджується в коментарі Аміна.
Бот

35

Хоча правильно, що createдзвінки newі тоді saveвелика різниця між двома альтернативами у їхніх повернених значеннях.

Saveповертає trueабо falseзалежно від того, вдало збережено об’єкт до бази даних чи ні. Потім це може бути використано для регулювання потоку, як показано в першому прикладі в питанні вище.

Createповерне модель незалежно від того, збережений чи ні об'єкт. Це має значення для коду вище, оскільки верхня гілка ifоператора завжди буде виконуватися, навіть якщо об'єкт завершує перевірку і не зберігається.

Якщо ви використовуєте createлогіку розгалуження, ви загрожуєте мовчазними збоями, що не стосується new+ save.

create! не страждає від тієї ж проблеми, що вона піднімається, та виняток, якщо запис недійсний.

createАльтернатива може бути корисною в контролерах , де respond_withвикористовуються API (JSON / XML) відповіді. У цьому випадку наявність помилок на об’єкті призведе до повернення помилок у відповіді зі статусом unprocessable_entity, який саме ви хочете отримати від API.

Я завжди використовуватиму опцію new+ saveдля html, особливо якщо ви покладаєтесь на повернене значення для контролю потоку.


6

#create - це скорочена версія нового та збереження. # творити! є викидом, якщо перевірка не була позитивною.


5

Я би другий відповіді вище. Плюс до цього create, не можна передавати falseаргумент, який ви можете зробити save. Передача falseяк аргумент пропустить усі перевірки рейки

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.