2011-03-09 40 views
2

看看下面的代碼:模型意識到params hash - Rails反模式?

class ChallengesController < ApplicationController 

    def update 
    @challenge = Challenge.find(params[:id]) 
    @challenge.update!(params[:challenge]) # never an expected error, show error page and give hoptoad notification 

    respond_to do |format| 
     format.html { redirect_to :action => 'index' } 
    end 
    end 

end 

class Challenge < ActiveRecord::Base 

    def update!(options) 
    if options[:accept] == '1' then 
     self.accepted = true 
     self.response_at = Time.now   
     self.shots = options[:shots] unless options[:shots].blank?    
     self.challengee_msg = options[:challengee_msg] unless options[:challengee_msg].blank? 
    else 
     self.accepted = false 
     self.response_at = Time.now 
    end 
    end 

end 

是它認爲不好的做法爲模型要注意params哈希表被傳遞給它?如果是這樣,你會如何重構,以便遵循「最佳實踐」?

回答

1

不,這是一種可接受的模式。它通常使用像這樣,內置active_record方法update_attributes。

@challenge = Challenge.find(params[:id]) 
if @challenge.update_attributes(params[:challenge]) 
    flash[:success] = "Challenge updated" 
    redirect_to @challenge 
else 
    render :action=>:edit 
end 

這將採用值的散列並自動設置您發送的屬性(除非它們受attr_protected保護)。

+0

要明確,你不需要實現update_attributes - 該方法已經存在了你。 –

0

,如果我猜對了,你有一定的操作要進行時,你accept有不同的情況下,如果接受的是假的,shotschallenge_msg應該是零

這可以在幾個方面進行

做到這一點的看法,可能與一些JavaScript腳本,你可以刪除和隱藏shotschallenge_msg領域,並提交表格相應

或控制器,你必須設定一個shots第二challenge_msg爲零做一樣的東西:

if params[:challenge][:accepted] == "0" 
    params[:challenge][:shots]   = nil 
    params[:challenge][:challenge_msg] = nil 
end 

@challenge.update_attributes(params[:challenge]) 

或模型,你可以使用像before_save回調將其保存,如果accept之前設置shotschallenge_msg爲零要做的就是假的

只是一些建議改善你的代碼,希望它有幫助=)

2

有一件事是,如果你傳遞params到你的模型中,並用它分散,採用先做一個.dup的做法。沒有什麼更令人沮喪的,然後試圖弄清楚爲什麼路由搞砸了,只是找到一個模型的某個地方一直在刪除params散列鍵。另外,如果因任何原因將參數散列傳遞給模型,請確保在該模型上具有attr_accessible。您需要將params視爲未經過處理的用戶輸入。