我一直在关注Michael Hartl的rails教程,并且已经在Signup confirmation处理了他建议的扩展,让用户点击电子邮件链接来激活他们的帐户。为了管理激活,我正在使用state_machine gem,但是当我尝试激活用户帐户时,我收到错误“无法通过以下方式转换状态:激活:挂起(原因:密码太短(最小为6个字符)) )”。 对我来说,似乎state_machine正在实现更新状态字段的数据库操作以某种方式导致与用户记录相关联的验证(可能与has_secure_password方法相关联)被触发并失败。 我在一年前遇到过关于该主题的另一个stackoverflow问题here,但是阅读有关该问题的评论似乎并不是解决方案。
我的用户模型(user.rb)代码如下(它基本上是6.29列表中的教程代码加上状态机的添加)。 [抱歉,无法提供链接,因为stackoverflow不允许我超过2个链接!]
class User < ActiveRecord::Base
validates :name, presence: true, length: { maximum: 50 }
VALID_EMAIL_REGEX = /\A[\w+\-.]+@[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
在rails控制台中,state_machine代码似乎正在解释数据库中的值ok,因为我可以获取用户记录以及何时执行user.can_activate?和user.can_deactivate?它正在回归我的期望。但是当我尝试做user.activate时!或user.deactivate!我收到密码太短错误。有关如何解决此问题的任何建议吗?
答案 0 :(得分:1)
通过更改代码以省去state_machine并直接更新数据库中的state字段,我找到了答案。然后我发现用户记录的所有更新导致密码验证被触发并出现密码长度错误(因此state_machine没有问题)。 如上所述here,解决方案是通过将上面的“验证”行更改为以下内容,如果密码不是要更新的属性之一,则阻止密码验证发生:
validates :password, length: { minimum: 6, maximum: 50 }, :if => :validate_password?
def validate_password?
password.present? || password_confirmation.present?
end
一旦更改,state_machine功能就可以正常工作。