2

我一直在關注Michael Hartl的rails教程,並且一直在解決他在Signup confirmation中建議的擴展,讓用戶點擊通過電子郵件發送的鏈接來激活他們的帳戶。要管理激活,我使用了state_machine gem,但是當我嘗試激活用戶帳戶時,出現錯誤「無法通過以下方式轉換狀態:activate from:pending(原因:密碼太短(最少爲6個字符) )」。 對我來說,似乎state_machine執行的數據庫操作更新狀態字段會以某種方式導致與用戶記錄相關的驗證(可能與has_secure_password方法關聯)被觸發並失敗。 一年前,我在這個主題上遇到了另一個關於該主題的stackoverflow問題here,但閱讀關於該問題的評論似乎並不是一個解決方案。Rails state_machine轉換導致密碼驗證錯誤

我的用戶模型(user.rb)代碼在下面(它基本上是列表6.29中的教程代碼加上一個狀態機)。 [!對不起,不能提供作爲計算器是不是讓我超過2個鏈接的鏈接]

class User < ActiveRecord::Base 
    validates :name, presence: true, length: { maximum: 50 } 
    VALID_EMAIL_REGEX = /\A[\w+\-.][email protected][a-z\d\-]+(\.[a-z]+)*\.[a-z]+\z/i 
    validates :email, presence: true, format: { with: VALID_EMAIL_REGEX }, 
    uniqueness: { case_sensitive: false } 
    before_save { email.downcase! } 
    validates :password, length: { minimum: 6, maximum: 50 } 
    has_secure_password 
    before_create :create_remember_token 

    state_machine initial: :pending do 
    state :pending, value: 0 
    state :active, value: 1 

    event :activate do 
     transition :pending => :active 
    end 

    event :deactivate do 
     transition :active => :pending 
    end 
    end 

    def initialize 
    super() 
    end 

我的數據庫用戶表結構是:

create_table "users", force: true do |t| 
t.string "name" 
t.string "email" 
t.datetime "created_at" 
t.datetime "updated_at" 
t.string "password_digest" 
t.string "remember_token" 
t.boolean "admin",   default: false 
t.string "token" 
t.integer "state" 
end 

在軌安慰state_machine代碼似乎要解釋數據庫中的值ok,因爲我可以獲得用戶記錄,並且當我做user.can_activate時?和user.can_deactivate?它回報我的期望。但是當我嘗試做user.activate!或user.deactivate!我得到的密碼太短錯誤。有關如何解決這個問題的任何建議?

回答

1

我找到了答案,通過更改代碼來省略state_machine並直接更新數據庫中的狀態字段。然後,我發現所有用戶記錄的更新都導致密碼驗證觸發並且出現密碼長度錯誤(因此state_machine沒有問題)。 如上所述here溶液是防止密碼驗證的發生,如果密碼不通過改變「只會驗證」線的上方,以被更新的屬性中的一個:

validates :password, length: { minimum: 6, maximum: 50 }, :if => :validate_password? 
def validate_password? 
    password.present? || password_confirmation.present? 
end 

一旦被改變state_machine功能作品精細。