2009-07-27 63 views

回答

46

你可以使用的ActiveRecords回調一個在您的用戶模型,例如類似的東西:

before_save { |user| user.username = user.username.downcase } 
+1

有關ActiveRecord回調的更多信息:http://api.rubyonrails.org/classes/ActiveRecord/Callbacks.html – Zargony 2009-07-27 10:10:22

+1

如果您有許多像這樣的鉤子和/或許多對屬性執行的操作,您也可以爲它們創建方法並給予該方法名稱而不是lambda表達式。 如果您有許多旨在更改屬性的回調,您可能還會看到[attribute-filters](http://rubydoc.info/gems/attribute-filters/1.2.2/)gem,它簡化了該過程。 – siefca 2012-08-03 17:37:47

0

在一般情況下,該窗體上提交按鈕應該委託給一個控制器動作 其中PARAMS [:用戶名可用。您可以在執行 SomeModel.update(params)或創建(params)之前將其小寫。

所以你可以在控制器動作中做到這一點。

+0

您需要考慮緊密耦合控制器和模型的後果。當兩個控制器需要創建此模型的實例時會發生什麼?如何使用控制檯創建用戶,並且開發人員忘記了該用戶名應該是無用的?單元測試怎麼樣?我認爲更好的方法是使用由effkay建議的ActiveRecord回調。 – 2009-07-27 09:04:01

+0

是的,我也贊成他。我的推理:只要它在一個地方,我真的不在乎。它看起來並不像OP的問題有多個地方..所以我去了可能可行的最簡單的事情。另外,你可能並不總是有一個模型..在這種情況下,但它看起來像OP應該使用一個。 – Gishu 2009-07-27 09:51:07

70

你應該覆蓋屬性作者:

class User < ActiveRecord::Base 
    def username=(val) 
    write_attribute(:username, val.downcase) 
    end 
end 
0

我建議增加一個Observer到模型上,做在before_save方法這個動作。然後,無論哪個控制器或動作創建該用戶名,都保證小寫用戶名,並且如果在觀察者內部執行任何操作時出現問題,則拋出異常並且該對象不會保存。

編輯:請注意,你不能不能做一個Model.save內before_save綁定到該模型,否則你最終在一個無限循環。你需要做一個update_attributes什麼的。

11

您的用戶模型(模型/ user.rb),採取ActiveRecord的回調的優勢:

before_save do 
    self.username = self.username.downcase 
end 
4

我花了一段時間查找從利用該代碼阻止我的錯誤。每次我試圖攔截一個屬性並在保存之前將其更改爲false時,我的數據庫都會回滾。

我在這裏提供我的答案,因爲此線程是完成此任務的第一個Google結果,但未覆蓋整個返回的false問題。

如果您的任何回調返回false所有內容都會回滾到db中。

我試圖設置要創建的優惠,以便不被數據庫或@offer.accepted = false接受。問題在於這一行導致整個方法返回false並回滾整個過程。

我固定它通過一個隱含的回報true後來

代碼工作折騰:

before_save {|offer| offer.accepted = false; true}

外賣:如果你想讓他們成功您的回調無法返回false

來源:rails 3 : Do i need to give return true in a before_save callback for an object.save to work?

1
def username=(str) 
super(str.downcase) 
end 

我認爲這要容易得多。

相關問題