Различия в рельсах между новым + сохранить и создать - PullRequest
63 голосов
/ 20 марта 2012

Я новичок в rails и не понимаю различий между использованием методов new + save и метода create.

def create
    @item = Item.new(params[:item])

    respond_to do |format|
      if @item.save
        format.html { redirect_to @item, notice: 'Item was successfully created.' }
        format.json { render json: @item, status: :created, location: @item }
      else
        format.html { render action: "new" }
        format.json { render json: @item.errors, status: :unprocessable_entity }
      end
    end
end

и:

  def create

    respond_to do |format|
      if Item.create(params[:item])
        format.html { redirect_to @item, notice: 'Item was successfully created.' }
        format.json { render json: @item, status: :created, location: @item }
      else
        format.html { render action: "new" }
        format.json { render json: @item.errors, status: :unprocessable_entity }
      end
    end
  end

Ответы [ 4 ]

116 голосов
/ 08 марта 2013

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

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

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

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

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

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

50 голосов
/ 20 марта 2012

Внутренне create звонки new, затем save в любом случае:

  def create(attributes = nil, options = {}, &block)
    if attributes.is_a?(Array)
      attributes.collect { |attr| create(attr, options, &block) }
    else
      object = new(attributes, options, &block)
      object.save
      object
    end
  end
18 голосов
/ 20 марта 2012

new создает объект, но не сохраняет его.

create создает объект , а сохраняет его, то есть .new и .save

create! создает объект и пытается сохранить его, но вызывает исключение, если проверки не пройдены, например, .new и .save!

Один из элементов путаницы заключается в том, что выше описаны действия, которые вы выполняетеобъект, но похожие имена также присваиваются методам контроллера, особенно в среде RESTful.Например, у вас есть действие создания ...., которое создает новый объект, а затем сохраняет его, и другое действие создания, которое просто создает объект.

Если вам интересно "зачем создавать объект, если яя не собираюсь его спасать?Учтите это - система «пытается» сохранить объект, но проверка препятствует этому, и пользователю предлагается заполнить дополнительную информацию в форме, возможно, обязательные поля.Кто-то хочет, чтобы объект все еще создавался (.new), пока он продолжается, и он будет содержать значения, которые были назначены до сих пор.Однако на самом деле он не получает save d, пока не пройдет валидацию.

4 голосов
/ 20 марта 2012

когда вы используете, rails фактически создает записи, но не сохраняет их, поэтому в процессе вы также можете назначить smth

@item = Item.new(params[:item])

но при использовании:

if Item.create(params[:item])
.....

немедленно создаст и сохранит

Вы можете проверить это с помощью rails c

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...