Ruby on rails 4 索引用户在rails/Desive中的解锁令牌唯一验证错误

Ruby on rails 4 索引用户在rails/Desive中的解锁令牌唯一验证错误,ruby-on-rails-4,devise,Ruby On Rails 4,Devise,我使用的是Rails4和Desive,当我试图从管理控制台更新用户时遇到了一个问题(我使用的是RailsAdmin)。每次我尝试更新时,都会出现一个错误: ActiveRecord::RecordNotUnique (PG::UniqueViolation: ERROR: duplicate key value violates unique constraint "index_users_on_unlock_token" 这可能是因为大多数用户的解锁令牌字段为空。但是可以为空的字段

我使用的是Rails4和Desive,当我试图从管理控制台更新用户时遇到了一个问题(我使用的是RailsAdmin)。每次我尝试更新时,都会出现一个错误:

    ActiveRecord::RecordNotUnique (PG::UniqueViolation: ERROR:  duplicate key value violates unique constraint "index_users_on_unlock_token"
这可能是因为大多数用户的解锁令牌字段为空。但是可以为空的字段仍然可以被索引吗?解锁令牌仅在用户被锁定在其帐户之外时设置,对吗

通过在确认令牌字段中输入一个随机字符串,我可以很容易地避免这个问题,但这似乎是一个不好的处理方法。还有更好的主意吗

My Users表定义(好的,是它的相关部分):

我的日志中的错误:

  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.

在评论中讨论之后,根据日志中的错误消息判断,该值似乎确实被设置为空字符串,而不是nil/NULL(
[“解锁令牌”,“解锁令牌]”])
)。我从未使用过rails\u admin,但它是否会在默认情况下向您显示一个包含所有用户字段的表单,而您只需将
unlock\u标记保留为空(这会导致问题,因此您会输入一个随机字符串)?您需要对此进行更改,以便根本不接触属性(即,您可以告诉rails_admin避免属性吗?-我不明白您为什么要手动编辑解锁令牌列),或者找到一种方法告诉rails_admin它应该将该属性的空字符串转换为nil。或者,您可以确保将
unlock_token
的空白字符串更改为nil(可能还有其他属性,例如其他令牌)。或者,您可以使用nilify_blanks gem之类的工具来实现这一点


非常奇怪的是,只有
unlock_令牌
正在更新(当然除了
updated_at
之外),但是日志中没有更多的上下文(即从参数击中动作的点到视图渲染结束),很难判断为什么会发生这种情况。

在评论中讨论之后,从日志中的错误消息判断,该值似乎确实被设置为空字符串,而不是nil/NULL(
[“unlock_token”,“”]
)。我从未使用过rails\u admin,但它是否会在默认情况下向您显示一个包含所有用户字段的表单,而您只需将
unlock\u标记保留为空(这会导致问题,因此您会输入一个随机字符串)?您需要对此进行更改,以便根本不接触属性(即,您可以告诉rails_admin避免属性吗?-我不明白您为什么要手动编辑解锁令牌列),或者找到一种方法告诉rails_admin它应该将该属性的空字符串转换为nil。或者,您可以确保将
unlock_token
的空白字符串更改为nil(可能还有其他属性,例如其他令牌)。或者,您可以使用nilify_blanks gem之类的工具来实现这一点


非常奇怪的是,只有
unlock\u令牌
正在更新(当然除了
updated\u在
之外),但是没有更多的日志上下文(即从参数击中动作的点到视图渲染结束),很难判断发生这种情况的原因。

是的,我认为解锁令牌仅在用户想要解锁其帐户时设置,并且一个唯一索引应允许多个空值。您能否确认db/版本(看起来像postgresql)。您能显示数据库中的表定义吗?还有,development.log消息,关于何时更新用户?谢谢tim,我已经发布了上面的表信息。开发日志给出了与我上面提到的相同的错误,只是说密钥(null)已经存在-您需要完整的跟踪吗?psql——版本为9.1.3。奇怪的是,当我以那个用户的身份登录并更新他们的详细信息时,一切正常。只有当我以管理员身份登录(到rails管理员)时才会失败,更新另一个用户的帐户为什么需要在该列上创建这样的索引?另一件事,
NULL
被忽略“但是,在这个比较中,两个NULL值被认为是不相等的。”索引是由designe自动添加的,因此我假设它在那里是有原因的是,索引用于快速查找,唯一性是因为解锁密钥必须特定于用户。来自dev日志的信息有助于确认传递给action的参数、正在执行的SQL等。例如,上面的消息没有提到NULL,只是违反了唯一索引,因此,如果,例如,该值实际上被设置为空字符串,而不是NULL,而另一行已经有空字符串,该怎么办?你关于它只是管理员编辑的评论也让我怀疑类似这样的行为与普通用户更新自己的行为不同。是的,我认为只有当用户想要解锁他们的帐户时才设置unlock_令牌,并且一个唯一索引应该允许多个空值。您能否确认db/版本(看起来像postgresql)。您能显示数据库中的表定义吗?还有,development.log消息,关于何时更新用户?谢谢tim,我已经发布了上面的表信息。开发日志给出了与我上面提到的相同的错误,只是说密钥(null)已经存在-您需要完整的跟踪吗?psql——版本为9.1.3。奇怪的是,当我以那个用户的身份登录并更新他们的详细信息时,一切正常。只有当我以管理员身份登录(到rails管理员)时才会失败,更新另一个用户的帐户为什么需要在该列上创建这样的索引?另一件事,
NULL
被忽略“但是,在这个比较中,两个NULL值被认为是不相等的。”索引是由designe自动添加的,因此我假设它在那里是有原因的是,索引用于快速查找,唯一性是因为解锁密钥必须特定于用户。来自dev日志的信息有助于确认传递给action的参数、正在执行的SQL等。例如,上面的消息没有提到NULL,只是那个惟一的inde
  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.