2017-06-02 63 views
0

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

我在这里的问题是,我怎样才能发送正确的响应,在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

这是因为你是不是在你的模型验证,所以当它试图创建记录失败,但有例外。

为了避免这种情况,您可以在您的模型中添加一个验证,该验证将检查该列是否唯一;如果验证成功,则记录将被创建,否则将返回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出现)。

+0

不错!我没有意识到这个错误(ActiveRecord :: RecordNotUnique)是在数据库级别,所以这就是为什么应用程序没有捕获它。 –

+0

@PedroGabrielLima是的,通过模型验证,您将在插入数据库之前捕获错误,并且您的控制器将发送正确的响应;所以它应该解决问题(如果没有,请不要忘记接受答案 - 点击勾号)。 – Gerry