Rails ajax调用500内部服务器错误

时间:2017-06-02 22:13:06

标签: ruby-on-rails ajax

我在使用respond_to方法时遇到问题:当模型被保存时,它会以正确的json格式返回。但是,当模型没有得到保存时,因为像ActiveRecord :: RecordNotUnique这样的错误,rails返回另一个响应,它不是我的:“已完成500内部服务器错误”并且返回的响应转到ajax错误功能。

我的问题是,如何发送正确的响应,即else语句中的响应,这样我就可以向用户显示正确的错误消息。

我正处于开发模式。

为了简单起见,我稍微更改了代码。

感谢。

控制器:

def create 
  @distribuicao = DistribuicaoPorCargo.new(distribuicao_por_cargo_params)
  respond_to do |format|
    if @distribuicao.save
      format.json { render json: @distribuicao.distribuicao, status: :created }
    else
      format.json { render json: @distribuicao.errors.full_messages, status: :unprocessable_entity }
    end
  end
end

的.js:

$.ajax 
    url: '/distribuicao_por_cargos'
    type: 'POST'
    dataType: 'JSON'
    data: {
      data: JSON.stringify(data_send_to_server)
    }
    success: (data, textStatus, jqXHR) ->
      console.log("AJAX Sucesss: #{textStatus}")
    error: (jqXHR, textStatus, errorThrown) ->
      console.log("AJAX Failed: #{textStatus}")

日志:

Started POST "/distribuicao_por_cargos" for 187.110.216.111 at 017-06-02 17:32:22 -0300
Cannot render console from 187.110.216.111! Allowed networks: 127.0.0.1, ::1, 127.0.0.0/127.255.255.255
Processing by DistribuicaoPorCargosController#create as JSON
Parameters: {"concurso_id"=>"2", "local_da_prova_id"=>"6", "tabela"=>"{\"cargo_id\":\"4\",\"quantidade_de_candidatos\":\"10\"},{\"cargo_id\":\"9\",\"quantidade_de_candidatos\":\"10\"},{\"cargo_id\":\"12}]"}
Concurso Load (0.4ms)  SELECT  "concursos".* FROM "concursos" WHERE "concursos"."id" = $1 LIMIT $2  [["id", 2], ["LIMIT", 1]]
LocalDaProva Load (0.2ms)  SELECT  "local_da_provas".* FROM "local_da_provas" WHERE "local_da_provas"."id" = $1 LIMIT $2  [["id", 6], ["LIMIT", 1]]
(0.1ms)  
BEGIN 
LocalDaProva Load (0.3ms)  SELECT  "local_da_provas".* FROM   "local_da_provas" WHERE "local_da_provas"."id" = $1 LIMIT $2  [["id", 6], ["LIMIT", 1]] SQL (1.5ms)  
INSERT INTO "distribuicao_por_cargos" ("created_at", "updated_at", "local_da_prova_id", "distribuicao") VALUES ($1, $2, $3, $4) RETURNING "id"  [["created_at", 2017-06-02 20:32:23 UTC], ["updated_at", 2017-06-02 20:32:23 UTC], ["local_da_prova_id", 6], ["distribuicao",   "[{\"cargo_id\":\"4\",\"quantidade_de_candidatos\":\"10\"},{\"cargo_id}]"]] 
(0.2ms)  
ROLLBACK
Completed 500 Internal Server Error in 108ms (ActiveRecord: 6.3ms)

 ActiveRecord::RecordNotUnique (PG::UniqueViolation: ERROR:  duplicate    key value violates unique constraint "index_distribuicao_por_cargos_on_local_da_prova_id"
DETAIL:  Key (local_da_prova_id)=(6) already exists.
: INSERT INTO "distribuicao_por_cargos" ("created_at", "updated_at", "local_da_prova_id", "distribuicao") VALUES ($1, $2, $3, $4) RETURNING "id"):

1 个答案:

答案 0 :(得分:1)

这是因为您没有在模型中进行验证,所以当它尝试创建记录时,它会失败,但有例外。

为避免这种情况,您可以在模型中添加验证,以验证列是否唯一;如果验证成功,则将创建记录,否则它将返回false并创建错误消息(而不是引发异常)。

您可以在模型验证中添加uniqueness: true,例如:

class DistribuicaoPorCargo < ApplicationRecord
  # scopes, callbacks, ...

  validates :local_da_prova_id, uniqueness: true
  # more validations
end

这样,您的控制器将回复:

render json: @distribuicao.errors.full_messages, status: :unprocessable_entity

并且不会引发异常(阻止Completed 500 Internal Server Error显示)。