2011-09-11 32 views
0

我有一個用戶模型三個字段,:電子郵件:DISPLAY_NAME和:處理。句柄在:display_name的幕後創建。Rails的驗證問題

我使用以下驗證:

validates :display_name, :presence => :true, :uniqueness => { :message => "Sorry, another user has already chosen that name."}, :on => :update 
    validates :email, :presence => :true, :uniqueness => { :message => "An account with that email already exists." } 

我用手柄作爲模型的to_param。如果用戶沒有通過提交驗證:DISPLAY_NAME已經存在,則試圖改變它,並重新提交表單時,Rails似乎使用新的手柄作爲電子郵件驗證 - 換句話說,它假定電子郵件沒有按不屬於當前用戶,並且電子郵件驗證失敗。此時,Rails假定更改後的顯示名稱/句柄是用於查找的變量,並且更新操作根本無法完成,因爲它無法根據新句柄找到用戶。

這裏的更新方法:

def update 
    @user = User.find_by_handle(params[:id]) 
    @handle = params[:user][:display_name] 
    @user.handle = @handle.parameterize 
    ... 
end 

當驗證失敗,第一次在一個重複的電子郵件不會發生這個問題,所以我假設它的東西,約我寫的更新方法的方式 - - 也許我應該嘗試設置模型中的手柄?

回答

2

也許我應該嘗試在模型中設置句柄?

^這。

控制器是不要做這樣的事情的地方。如果模型邏輯發生在幕後,超出用戶的控制範圍,爲什麼把它放在控制器代碼中?

而是在before_save過濾器中執行此操作,該過濾器只有在確定所選顯示名稱可用並且該記錄被視爲有效後才能運行。這樣,handle不會對緩存的記錄被改變,直到它實際上是致力於分貝,消除了不正確生成的URL的問題。

before_save :generate_handle 
... 

def generate_handle 
    self.handle = display_name.parameterize 
end 
+0

我不記得我爲什麼將它設置在控制器中......可能是出於方便。 – Slick23