2016-05-02 4 views
3

私は、モバイルアプリケーション用のRailsバックエンドAPIを作成しており、受け入れられたステータスコードで一意のレコードを検証したいと考えています。ステータスが受け付けられた一意の検証を処理する

@Why?

モバイルアプリからのエントリを保存するときに、重複したレコードをRailsに保存しないようにしたいが、エラーステータスではなくRailsからモバイルアプリに「受け入れられたステータスコード」を送信して、 。私が好きな

モデル

class Entry < ActiveRecord::Base 
    validates :uuid, uniqueness: true 
end 

コントローラ

def create 

    # Check if the same record already exists 
    entry = Entry.find_by(uuid: entry_params[:uuid]) 

    if entry.present? 
     render json: {errors: {message: 'The same uuid already exists.'}}, status: :accepted 
     return 
    end 

    entry    = Entry.new 
    entry.attributes = entry_params 

    if entry.save 
     render json: entry, status: :created 
    else 
     render json: entry.errors, status: :unprocessable_entity 
    end 
    end 

上記のコードは動作しますが、私はきちんと代わりにレールの検証を使用することができる場合、私は疑問に思って。

これは私が試みたものですが、残念なことにユニークなuuidエラーを取得できませんでした。この状況に対処するためのよりよい方法はありますか?

ApplicationControllerに

rescue_from ActiveRecord::RecordNotUnique, with: :record_not_unique 

    def record_not_unique 
     render json: {errors: {message: 'Record not unique.'}}, status: :accepted 
    end 

答えて

1

唯一性検証では例外が発生しません。検証されたentryレコードにerrorsオブジェクトを設定するだけで、保存できなくなります。

  • は、あなたのモデルに一意性の検証を取り除き、基礎となるデータベース・テーブルの列にUNIQUE制約を設定取得:あなたは、原則的に2つのオプションがあります。次に、saveコールは、データベースによってトリガーされたActiveRecord::RecordNotUnique例外を発生させます。そしてあなたは実際にあなたが投稿した通りにrescue_fromにできるはずです。

  • は例外なしで行う(rescue_fromをダンプ)し、所定の位置に一意性の検証を残して、あなたのコントローラに手動でerrorsを処理する、の線に沿って何か:

    def create  
        entry = Entry.new(entry_params) 
    
        if entry.save 
        render json: entry, status: :created 
        elsif entry.errors.count == 1 && entry.errors[:uuid].first == "has already been taken" 
        render json: {errors: {message: 'The same uuid already exists.'}}, status: :accepted 
        else 
        render json: entry.errors, status: :unprocessable_entity 
        end 
    end 
    
+0

は非常に明確を提供いただき、ありがとうございます見る! –

0

トリガされた例外が効果的にフェイルファストしますので、あなたの要求をあなたはrescue_fromを使用することはできません。代わりに、これらの成功/失敗の結果(非ユニークではない)をキャッシュ/ロギングする必要があります。

レコードが作成されたときにステータス201を送信し、重複レコードが決定されたときにステータス202を送信できます。それぞれのステータスをバケットでバッチの終わりに、最後に後処理を実行します。

関連する問題