2012-07-11 45 views
1

我正在通过Head First Rails工作,并且遇到一些令我困惑的代码。代码的目标是在创建新记录时检查是否发生错误。如果出现错误,那么目标是重新显示页面。如果没有错误,则目标是将记录保存到数据库。下面是书中给出的控制器代码:Rails控制器Object.save

def create 
    @ad = Ad.new(params[:ad]) 
    if @ad.save 
     redirect_to "/ads/#{@ad.id}" 
    else 
     render :template => "ads/new" 
    end 
end 

这段代码唯一令我困惑的是事实行(如果@ ad.save)。现在,我知道这一行正在测试以查看是否有错误。如果存在,则返回false,如果不存在,则返回true。但是,我注意到如果没有错误存在(它返回true),记录实际上被保存。我认为ruby中的“如果”语句只是测试一个条件,但在这种情况下,条件正在测试和执行。奇怪的是,如果我添加另一个@ ad.save,数据库不会保存记录两次。像这样:

def create 
    @ad = Ad.new(params[:ad]) 
    if @ad.save 
      @ad.save 
     redirect_to "/ads/#{@ad.id}" 
    else 
     render :template => "ads/new" 
    end 
end 

此代码与第一位代码完全相同。为什么在第一位代码中执行@ ad.save,以及第二位代码中@ ad.save没有执行两次(仅创建一条记录)?

回答

1

您对Ruby中的if语句的假设是错误的。他们实际上可以执行代码。

def return_true 
    puts 'inside method' 
    true 
end 

if return_true 
    puts "it ran some code" 
end 

# output will be: 
# inside method 
# it ran some code 

在第二个例子中,保存至少运行一次。如果@as.save的结果是真的,那么它会再次运行。如果它正在经历if分支的第一部分,那么其他东西会阻止它被保存到数据库两次,但没有足够的信息可以告诉我为什么。这可能是因为你有一个独特的禁忌。试试做@ad.save!。如果存在任何验证错误,爆炸版本将引发错误。