2016-11-13 63 views
2

考慮用戶模型具有以下字段:多步的ActiveRecord的模型驗證

  • 名(必填)
  • 姓(必填)
  • 電子郵件(必填)
  • 密碼(必填)
  • 電話(必填,大小:10位數)
  • 地址(必填)

和多步驟的註冊表格下面的步驟:

  • 與田姓,名和電子郵件
  • 與密碼,電話和地址第2步第1步。

您將如何創建解決方案來驗證每個步驟中的輸入?

標準ActiveRecord的方式不起作用,因爲它一次驗證所有字段。

我已經爲這個問題創建了一個解決方案,但是它變成了一個複雜的代碼,所以我正在尋找替代方案。

+1

基於'step'屬性的條件Lambda?當然,你可能會有一些複雜的控制器代碼。 'validates:first_name,presence:true,if:lambda {| user | user.step === 1}'。如果你找到了一個很好的答案,那麼Rails社區很想知道:) –

+0

你需要一個'User'實例嗎?您可以沿途創建一個或兩個臨時非用戶模型,然後在完成後將它們轉換爲真正的「用戶」。總體上相同的邏輯,但驗證的條件性將通過模型的分離來處理,而不是'User'中的一堆複雜性。 –

回答

2

就我個人而言,我會讓模型管理它自己的驗證,並將管理每個步驟的驗證的邏輯移動到那。

現在,這可能不是最優雅的方法,但它的有效性並沒有太多混淆代碼。

向模型添加一個step瞬態屬性。

attr_accessor :step 

添加下面的方法模型,以檢查是否在正確的一步:

def on_step(step_number) 
    step == step_number or step.nil? 
end 

原因step.nil? - 這具有的優點是,如果你想在這個模型中使用的驗證不使用步驟根本不要爲模型上的步驟賦值,並且該方法將允許返回true,從而始終執行驗證。

更改驗證處理只有在正確的一步或者不使用步驟

validates :first_name, if: "on_step 1", presence: true 
validates :last_name, if: "on_step 1", presence:true 
validates :email,  if: "on_step 1", presence:true 

validates :password, if: "on_step 2", presence:true 
validates :phone,  if: "on_step 2", format:{ with: TEL_REGEX }, allow_blank: false 
validates :address, if: "on_step 2", presence:true 

當然不要忘了用硬編碼它來設置模型當前步驟,例如繞過表單的隱藏字段(如果爲每個步驟呈現單獨的表單)並更改您的參數以接收它。