2

I use devise for authentication and in registration controller if user cannot be created due to some reason then it produces json response as

{"email":["has already been taken"],"password":["doesn't match confirmation"],"username":["has already been taken"]}

but i want this to be changed to the following

{"error":{"email":{"has already been taken"},"password":{"doesn't match confirmation"},"username":{"has already been taken"}}}

How can i do this?

4

4 回答 4

8

作为参考,以防其他人在使用 Devise 尝试登录失败时查找如何自定义 json 错误响应时偶然发现此问题,关键是使用您自己的自定义FailureApp实现。(您也可以使用这种方法来覆盖某些重定向行为。)

class CustomFailureApp < Devise::FailureApp
  def respond
    if request.format == :json
      json_error_response
    else
      super
    end
  end

  def json_error_response
    self.status = 401
    self.content_type = "application/json"
    self.response_body = [ { message: "Your email or password is incorrect."} ].to_json
  end
end

在您的 中devise.rb,查找以下config.warden部分:

  config.warden do |manager|
    manager.failure_app = CustomFailureApp
  end

一些相关信息:

起初我以为我必须重写Devise::SessionsController,可能使用recall传递给的选项,但正如这里warden.authenticate!提到的,“API 请求不会调用调用,仅用于导航请求。如果你想自定义 http 状态代码,在失败的应用程序级别这样做你会有更好的运气。”

https://github.com/plataformatec/devise/wiki/How-To%3a-Redirect-to-a-specific-page-when-the-user-can-not-be-authenticated

于 2016-02-09T18:50:23.480 回答
3

@quix 答案扩展(我不将其作为评论留下,因为它有格式问题)。

您也可以尽量减少重定义http_auth_body方法的覆盖:

class CustomFailureApp < Devise::FailureApp
  def http_auth_body
    return super unless request_format == :json
    {
      success: false,
      error: i18n_message
    }.to_json
  end
end
于 2016-11-16T08:17:32.693 回答
0

您应该创建一个 json.erb 文件并将其呈现在该错误中。 这个答案向您展示了如何做到这一点。

于 2012-11-27T06:19:06.383 回答
0
respond do |format|
    format.json { render json: {error: @your_model.errors }}
end

或者你应该试试

respond do |format|
    format.json { render json: {error: Hash[@your_model.errors.map {|k, v| k, v[0]] } }}
end
于 2012-11-27T06:24:37.167 回答