2012-03-20 41 views
43

我是新来的rails,我不明白使用新的+保存方法和创建方法之间的差异。新的+保存和创建rails之间的差异

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 

回答

38

内部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 
3
当你使用,轨道实际上是创造了记录,但没有保存,所以在这个过程中,你也可以指定不便

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

但当您使用:

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

它无线会立即创建并保存

你可以用rails c

+0

好的,但在我的情况下,使用新的+保存或只有直接创建有区别? – 2012-03-20 17:04:48

+0

不,没有区别,他们都在做同样的工作 – 2012-03-20 17:07:41

12

new检查它创建的对象,但不保存它。

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

create!创建该对象,并试图将其保存,但如果验证失败,引发了异常,例如.new.save!

混淆项目之一是以上是您对某个对象所采取的操作,但是对控制器方法也给出了相似的名称,特别是在RESTful环境中。例如,你有一个创建动作....它创建一个新的对象,然后保存它,另一个创建动作,只是做一个对象创建。

如果您想知道“如果我不打算保存它,为什么要创建一个对象?”考虑这一点 - 系统'尝试'保存对象 - 但验证会阻止它,并要求用户填写表单上的更多信息,也许是必填字段。我们希望这个对象在创建时仍然被创建(.new),并且它将保存迄今为止分配的值。然而它实际上并没有得到saved直到它通过了验证。

97

虽然它是正确的,create电话new然后save有他们的返回值的两个备选方案之间有很大的区别。

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

Create将返回模型,无论对象是否已保存。这对上述代码有影响,因为即使对象未通过验证并且未保存,if语句的顶部分支也将始终执行。

如果您使用带分支逻辑的create,则存在无声失败的风险,如果使用new + save,则不会发生这种情况。

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

我总是会用html的new + save选项,尤其是如果您依赖流量控制的返回值。

+0

“如果您使用带有分支逻辑的create,则存在无声失败的风险,如果您使用new + save,则不会发生这种情况。”感谢你! – jacoulter 2015-01-27 19:16:15

+0

对于对象验证和创建速记使用: '.create(...)。valid?' 它将返回true并创建对象或返回false并且什么也不做。 – neonmate 2015-04-22 12:45:21

+0

我说得对模态中的'new'和'save'更好吗? @nmott是你所说的HTML吗? – 2016-07-27 14:00:13

相关问题