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

时间:2014-02-22 03:11:18

标签: ruby-on-rails-4 devise

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

    ActiveRecord::RecordNotUnique (PG::UniqueViolation: ERROR:  duplicate key value violates unique constraint "index_users_on_unlock_token"

这可能是因为大多数用户的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

我的日志中的错误:

  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.

1 个答案:

答案 0 :(得分:6)

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

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