2012-07-11 44 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!。如果存在任何驗證錯誤,爆炸版本將引發錯誤。