new + save和create之间的rails的差异

时间:2012-03-20 16:56:59

标签: ruby-on-rails ruby-on-rails-3

我是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 个答案:

答案 0 :(得分:114)

尽管create调用new然后调用save是正确的,但两个替代品的返回值之间存在很大差异。

Save返回truefalse,具体取决于对象是否已成功保存到数据库。根据上述问题中的第一个例子,这可以用于流量控制。

无论对象是否已保存,

Create都将返回模型。这对上面的代码有影响,因为即使对象验证失败并且未保存,if语句的顶部分支也将始终执行。

如果您使用create分支逻辑,那么您将面临无声失败的风险,如果您使用new + save则不会出现这种情况。

create替代方案在respond_with用于API(JSON / XML)响应的控制器中非常有用。在这种情况下,对象上存在错误将导致错误在状态为unprocessable_entity的响应中返回,这正是您想要的API。

我总是会对html使用new + save选项,特别是如果您依赖流控制的返回值。

答案 1 :(得分:50)

内部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

答案 2 :(得分:18)

new创建对象但不保存它。

create创建对象保存它,即.new.save

create!创建对象并尝试保存它,但如果验证失败,则会引发异常,例如.new.save!

其中一个混淆项是上面是对对象执行的操作,但控制器方法也有类似的名称,尤其是在RESTful环境中。例如,你有一个创建动作....创建一个新对象,然后保存它,另一个创建动作只是一个对象创建。

如果你想知道“为什么要创建一个对象,如果我不打算保存它?”考虑这一点 - 系统'尝试'保存对象 - 但验证会阻止它,并且要求用户填写表单上的更多信息,可能是必填字段。一个人希望在此过程中仍然创建对象(.new)并且它将保存到目前为止已分配的值。但是,在通过验证之前,它实际上不会save d。

答案 3 :(得分:4)

当你使用时,rails实际上是创建记录但没有保存它,所以在这个过程中你也可以分配smth

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

但是当你使用:

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

它会立即创建并保存

您可以使用rails c

进行检查