快速示例:用戶將一個用戶名輸入到表單中,並且我需要在將該用戶名存儲到應用程序的數據庫中之前創建該文本用戶名,從而使其永久小寫。Ruby on Rails - 我可以在保存之前修改數據嗎?
我會在哪裏放這段代碼,以及如何訪問要小寫的數據?
謝謝。
快速示例:用戶將一個用戶名輸入到表單中,並且我需要在將該用戶名存儲到應用程序的數據庫中之前創建該文本用戶名,從而使其永久小寫。Ruby on Rails - 我可以在保存之前修改數據嗎?
我會在哪裏放這段代碼,以及如何訪問要小寫的數據?
謝謝。
你可以使用的ActiveRecords回調一個在您的用戶模型,例如類似的東西:
before_save { |user| user.username = user.username.downcase }
在一般情況下,該窗體上提交按鈕應該委託給一個控制器動作 其中PARAMS [:用戶名可用。您可以在執行 SomeModel.update(params)或創建(params)之前將其小寫。
所以你可以在控制器動作中做到這一點。
您需要考慮緊密耦合控制器和模型的後果。當兩個控制器需要創建此模型的實例時會發生什麼?如何使用控制檯創建用戶,並且開發人員忘記了該用戶名應該是無用的?單元測試怎麼樣?我認爲更好的方法是使用由effkay建議的ActiveRecord回調。 – 2009-07-27 09:04:01
是的,我也贊成他。我的推理:只要它在一個地方,我真的不在乎。它看起來並不像OP的問題有多個地方..所以我去了可能可行的最簡單的事情。另外,你可能並不總是有一個模型..在這種情況下,但它看起來像OP應該使用一個。 – Gishu 2009-07-27 09:51:07
你應該覆蓋屬性作者:
class User < ActiveRecord::Base
def username=(val)
write_attribute(:username, val.downcase)
end
end
我建議增加一個Observer到模型上,做在before_save方法這個動作。然後,無論哪個控制器或動作創建該用戶名,都保證小寫用戶名,並且如果在觀察者內部執行任何操作時出現問題,則拋出異常並且該對象不會保存。
編輯:請注意,你不能不能做一個Model.save內before_save綁定到該模型,否則你最終在一個無限循環。你需要做一個update_attributes什麼的。
您的用戶模型(模型/ user.rb),採取ActiveRecord的回調的優勢:
before_save do
self.username = self.username.downcase
end
我花了一段時間查找從利用該代碼阻止我的錯誤。每次我試圖攔截一個屬性並在保存之前將其更改爲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?
def username=(str)
super(str.downcase)
end
我認爲這要容易得多。
有關ActiveRecord回調的更多信息:http://api.rubyonrails.org/classes/ActiveRecord/Callbacks.html – Zargony 2009-07-27 10:10:22
如果您有許多像這樣的鉤子和/或許多對屬性執行的操作,您也可以爲它們創建方法並給予該方法名稱而不是lambda表達式。 如果您有許多旨在更改屬性的回調,您可能還會看到[attribute-filters](http://rubydoc.info/gems/attribute-filters/1.2.2/)gem,它簡化了該過程。 – siefca 2012-08-03 17:37:47