Rails 5.1: devise_token_auth returns 2 个错误,而只应找到 1 个

Rails 5.1: devise_token_auth returns 2 errors when only 1 should be found

类似于 this question for the regular devise gem, using devise_token_auth gem 显示相同的结果 - 验证错误在 json 响应中出现两次!?

来自日志:

Processing by DeviseTokenAuth::RegistrationsController#create as JSON
  Parameters: {"name"=>"Mickey Mouse", "email"=>"mickeymouse@gmail.com", "password"=>"[FILTERED]", "confirmPassword"=>"[FILTERED]", "confirm_success_url"=>"http://localhost:4200/register", "registration"=>{"name"=>"Mickey Mouse", "email"=>"mickeymouse@gmail.com", "password"=>"[FILTERED]", "confirmPassword"=>"[FILTERED]", "confirm_success_url"=>"http://localhost:4200/register"}}
Unpermitted parameters: :confirmPassword, :confirm_success_url, :registration
Unpermitted parameters: :confirmPassword, :confirm_success_url, :registration
   (0.2ms)  BEGIN
  User Exists (0.9ms)  SELECT  1 AS one FROM "users" WHERE "users"."email" =  LIMIT   [["email", "mickeymouse@gmail.com"], ["LIMIT", 1]]
   (0.8ms)  SELECT COUNT(*) FROM "users" WHERE "users"."provider" =  AND "users"."email" =   [["provider", "email"], ["email", "mickeymouse@gmail.com"]]
   (0.3ms)  ROLLBACK
Completed 422 Unprocessable Entity in 247ms (Views: 0.7ms | ActiveRecord: 6.9ms)

请注意 unpermitted_parameters 行显示了两次 - 这似乎表明有些奇怪(这些行不会通过 Postman 显示)。

我的用户模型没有标准指南中的任何额外内容,所以我的模型肯定没有 2 个唯一性或存在性验证,并且检查 gem 的源代码它似乎也没有那个.

这是模型:

class User < ActiveRecord::Base

  # Include default devise modules.
  devise :database_authenticatable, :registerable,
          :recoverable, :rememberable, :trackable, :validatable,
          :confirmable, :omniauthable
  include DeviseTokenAuth::Concerns::User
end

如果我从 Postman 调用这个端点,我得到相同的结果,这是返回的 json:

{
    "status": "error",
    "data": {
        "id": null,
        "account_id": null,
        "provider": "email",
        "uid": "",
        "name": null,
        "nickname": null,
        "image": null,
        "email": "mickeymouse@gmail.com",
        "created_at": null,
        "updated_at": null
    },
    "errors": {
        "email": [
            "has already been taken",
            "has already been taken"
        ],
        "full_messages": [
            "Email has already been taken",
            "Email has already been taken"
        ]
    }
}

Rails API 是使用 angular2-token 库从 Angular2 调用的,但这显然不是问题所在(给出 Postman 的结果)。

我怎样才能找到这个问题的原因或者我怎样才能猴子修补 gem 以消除第二个错误?

更新

如果我从模型中删除 :validatable 并进行自己的验证:

  validates_uniqueness_of :email

我得到了相同的结果,这很奇怪。

编辑:这个问题已经修复,只需升级您的gem! > v0.1.43.beta1


我发现 the issue 在 github 上有报道。

解决方法是删除 :validatable(电子邮件的唯一性仍会触发),然后滚动您自己的密码确认验证,如该问题所示(请参阅 stephanebruckert 那里的回复)并在此处转载:

引述: "validatable validates both the email and the password, which is why we shouldn't do any of those in models, otherwise it would be validated twice. In my case, only the email was validated twice, whereas I wasn't adding any extra validation in my model. So I ended up removing validatable and made my own validation on password and password_confirmation:"

  validates_presence_of :password, on: :create
  validates :password,
    length: { minimum: 8 },
    allow_blank: true
  validate  :password_complexity
  validates_confirmation_of :password
  validates_presence_of :password_confirmation, if: lambda {| u| u.password.present? }

  private

    def password_complexity
      return unless password
      if password.include?(username) || !password.match(/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)./)
        errors.add(:password, "Must include at least one lowercase letter, one uppercase letter and one digit")
      end
    end

虽然这确实解决了重复的电子邮件错误,但我现在收到“password_confirmation 不能为空错误”......这导致了一个兔子洞,发现 this issue。您将需要全部阅读,但基本上,api 应该 而不是 强制存在密码确认值(仅在表单本身中需要):)