Различия между .build, .create и .create! и когда их использовать?

Итак, в последнее время я все чаще и чаще вижу людей, использующих .build, .create и .create! в своих контроллерах. В чем разница от простого использования .new и передачи объекта param'd, а затем .save? Есть ли плюсы и минусы? Предлагает ли использование этих других методов преимущества?

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
169
0
65 545
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

#create - это более короткая версия new и save. #Создайте! выдает исключение, если проверка не была положительной.

Ответ принят как подходящий

Есть пара отличий, но они не большие:

  1. .create эквивалентен .new, за которым следует .save. Это просто более лаконично.
  2. .create! эквивалентен .new, за которым следует .save! (выдает ошибку, если сохранение не удается). Это также немного короче
  3. Я думаю, что .build - это по большей части, псевдоним для .new. Это работает в одну сторону в Rails 3 и другой способ в Rails <3.x

Однако наиболее важной частью является то, что эти методы можно вызывать через ассоциацию (has_many и т. д.) Для автоматического связывания двух моделей.

Я выбрал этот как наиболее правильный ответ из-за упоминания возможности связать с ними связанные модели - это интересное и важное отличие, которое я думаю об использовании .new и .save. Что требует дополнительной работы. Спасибо.

Tim Knight 31.12.2008 23:15

Небольшое уточнение по 3 - build делает немного больше, чем просто новое - он также устанавливает ссылку ассоциации.

Two Bit Gangster 26.04.2011 10:51

Как вы звоните через ассоциацию в отношениях «Многих-Многих»?

Grant Sayer 24.08.2011 15:27

Сборка отличается от Новой. Но разница не в том, что он устанавливает ссылку ассоциации (New делает это и для нового экземпляра). Разница в том, что Build заполняет вызывающий объект новым экземпляром, а New - нет. Так, например: Wall.posts.new дает вам новый пост, связанный с вашей стеной, но Wall.posts все еще остается пустым после этого вызова. Wall.posts.build дает вам новый пост, связанный с вашей стеной, и в вашем Wall.posts теперь есть одно сообщение.

Amin Ariana 01.12.2011 05:12

Разве это не просто псевдоним, без особой функциональности?

Gabriele Cirulli 09.08.2013 00:56

В Rails 4 я только что проверил консоль. Wall.posts.new и wall.posts.build заполняют объект стены одинаково. Значит, после wall.posts.new wall.posts не пуст, как утверждается в комментарии Амина.

Bot 13.06.2014 16:21

@AminAriana Тогда в чем разница между .build и .create? Согласно документации, .save также создаст новую запись в базе данных (вызывающий абонент с новым экземпляром?). Документы на .save: "If the model is new a record gets created in the database, otherwise the existing record gets updated"

LazerSharks 28.12.2014 01:12

Я бы поддержал приведенные выше ответы. Кроме того, для create нельзя передавать false в качестве аргумента, что можно сделать с save. Передача false в качестве аргумента пропустит все проверки рельсов

Хотя правильно, что create вызывает new, а затем save, между двумя альтернативами существует большая разница в их возвращаемых значениях.

Save возвращает либо true, либо false в зависимости от того, был ли объект успешно сохранен в базе данных или нет. Затем это можно использовать для управления потоком, как в первом примере в вопросе выше.

Create вернет модель независимо от того, был ли объект сохранен или нет. Это имеет последствия для приведенного выше кода в том смысле, что верхняя ветвь оператора if всегда будет выполняться, даже если объект не прошел проверку и не был сохранен.

Если вы используете create с логикой ветвления, вы подвержены риску тихих сбоев, чего не происходит, если вы используете new + save.

create! не страдает той же проблемой, что и вызывает исключение, если запись недействительна.

Альтернатива create может быть полезна в контроллерах, где respond_with используется для ответов API (JSON / XML). В этом случае наличие ошибок в объекте приведет к тому, что ошибки будут возвращены в ответе со статусом unprocessable_entity, что именно то, что вы хотите от API.

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

Другие вопросы по теме