rails/devise中的index_users_on_unlock_token唯一验证错误

Dav*_*ave 0 devise ruby-on-rails-4

我正在使用Rails 4并设计,当我尝试从我的管理控制台更新用户时遇到问题(我正在使用Rails管理员).每次我尝试更新时,都会给我一个错误:

    ActiveRecord::RecordNotUnique (PG::UniqueViolation: ERROR:  duplicate key value violates unique constraint "index_users_on_unlock_token"
Run Code Online (Sandbox Code Playgroud)

这可能是因为大多数用户的unlock_token字段为空.但是肯定可以为null的字段仍可以编入索引吗?只有当用户被锁定在他们的帐户之外时才设置unlock_token?

我可以通过在确认令牌字段中输入随机字符串来轻松避免此问题,但这似乎是处理它的一种不好的方法.有更好的想法吗?

我的用户表定义(以及它的相关部分):

create_table "users", force: true do |t|
    t.string   "email",                                               default: "",    null: false
    t.string   "encrypted_password",                                  default: "",    null: false
    t.string   "screen_name"
    t.string   "reset_password_token"
    t.datetime "reset_password_sent_at"
    t.datetime "remember_created_at"
    t.integer  "sign_in_count",                                       default: 0
    t.datetime "current_sign_in_at"
    t.datetime "last_sign_in_at"
    t.string   "current_sign_in_ip"
    t.string   "last_sign_in_ip"
    t.string   "confirmation_token"
    t.datetime "confirmed_at"
    t.datetime "confirmation_sent_at"
    t.integer  "failed_attempts",                                     default: 0
    t.string   "unlock_token"
    t.datetime "locked_at"
end
Run Code Online (Sandbox Code Playgroud)

我的日志错误:

  SQL (10.5ms)  UPDATE "users" SET "unlock_token" = $1, "updated_at" = $2 WHERE "users"."id" = 7  [["unlock_token", ""], ["updated_at", Mon, 24 Feb 2014 02:59:58 UTC +00:00]]
PG::UniqueViolation: ERROR:  duplicate key value violates unique constraint "index_users_on_unlock_token"
DETAIL:  Key (unlock_token)=() already exists.
Run Code Online (Sandbox Code Playgroud)

Tim*_*Tim 6

在评论中讨论之后,根据日志中的错误消息判断,该值看起来确实被设置为空字符串而不是nil/NULL(["unlock_token", ""]).我从来没有使用过rails_admin,但是它默认显示一个包含所有用户字段的表单而你只留下unlock_token空白(导致问题,所以你输入一个随机字符串)?您需要更改此设置,以便您根本不触摸该属性(即,您是否可以告诉rails_admin以避免属性? - 我无法理解您为什么要手动编辑解锁令牌列)或查找告诉rails_admin它应该为该属性将空字符串转换为nil的方法.或者,您可以确保将空字符串更改为nil unlock_token(也可能是其他属性 - 例如其他标记).或者,您可以使用类似nilify_blanks gem的东西来执行此操作.

奇怪的unlock_token是,只有正在更新(updated_at当然除外),但没有来自日志的更多上下文(即从参数点击动作直到视图渲染结束的点),很难说出为什么会发生这种情况.