2016-07-18 9 views
2

私はRailsが新しく、パラメータの検証とエラー応答の返答についていくつか質問があります。新しいRails 5 APIモードを使用してJSON APIを作成したいと考えています。Rails JSON APIのパラメータの検証とエラーの応答

私の知る限り、Railsはパラメータを検証するためのベースラインとして、「強いパラメータ」を使用することをお勧めします。たとえば、電話番号や電子メールのどちらかを必要とするUserクラスを作成したい場合は、まず自分のUsersControllerでこのようなものから始めます。私は何かが少し複雑たい場合

def create 
    @user = User.new(create_user_params) 
end 

def create_user_params 
    params.require(:user).permit(:email, :phone) 
end 

さて、私は次のよう

def create 
    arr_contains_at_least_one(params[:user], [:email, :phone]) 
    @user = User.new(create_user_params) 
end 

が追加される場合がありますこれは私の質問に私たちをもたらします。

両方のデフォルトのRailsのエラー(ActionController :: ParameterMissing)、またはカスタムエラーが発生した場合に、「かわいい」エラー応答を返すための最良の方法は何ですか?つまり、ブラウザでAPIエンドポイントを呼び出すと、わかりやすいメッセージとともに読み込み可能なJSONが返されます。私はプロダクションモードで私のサーバーを実行し、最初の例では、ユーザパラメータを提供することができない場合は、返品をレール:

An unhandled lowlevel error occurred. The application logs may have details. 

これは私がエンドユーザーにエラーを表示することを望んだ場合は特に、明らかに無意味です。ここでは、強力なパラメータパターンは、セキュリティとデータの完全性のためであり、ユーザーエクスペリエンスではないと仮定します。モデルフィールドの検証にも同じことが言えます。だから私は次のように調整する。

def create 
    return error_response("some error") unless arr_contains_at_least_one(params[:user], [:email, :phone]) 
    @user = User.new(create_user_params) 
end 

def error_response(msg, status = 400) 
    render json: {"code":status, "message": msg}, :status => status 
end 

これは動作しますが、今は手動でパラメータのチェック(必須パラメータが存在するかどうかをチェックするために、そのような電子メールアドレスなどのパラメータを検証するために)とそれに対応するエラー応答を書くことを強制しています。 Railsの組み込みフィールド検証もモデルで使用している場合、DRYの原則に違反しているようです。さらに、優れたエラー処理パターンを設計するには、かなりのカスタム実装が必要です。

私はいくつかのRailsの魔法を見逃しているのですか、私はここで正しい道にいるのですか?

EDIT:アクティブレコードの検証は、JSONレスポンス(http://guides.rubyonrails.org/active_record_validations.html)でかなり容易にラップすることができますが、パラメータの存在を確認するための質問はまだ残ります。すべての検証がモデルに生きるべき - フォームの往復を使用することになっ

答えて

2

のための機会を与えることをお勧めします。

強いパラメータは、属性をエンドユーザー割り当てから保護するためのインターフェイスを提供します。これにより、アクションコントローラのパラメータは、ホワイトリストに登録されるまでアクティブモデルの質量割り当てで使用することを禁止されます。

http://edgeapi.rubyonrails.org/classes/ActionController/StrongParameters.html

強いパラメータであなたホワイトリストのパラメータ場合、それはあなたがあなたのActiveRecordのモデルにそれらを-割り当てる質量のことができるようにすることを意味します。または、ホワイトリストに登録されていない属性はモデルに渡されません。

実際には、検証自体とは関係ありません。それらは、許可されていないパラメーター注入のためにモデルを保護するためのものです。

def create 
    @user = User.new(create_user_params) 
end 

def create_user_params 
    params.require(:user).permit(:email, :phone) 
end 

ので、あなたの例:

POST /users body={user: {email: '[email protected]', phone: '1234', some_other: 'some other'}} 

some_other属性を使用するとのActiveRecordの検証IS探しているものをお使いUser.new

に渡されません。お使いのモデルで

def create 
    @user = User.new(create_user_params) 
    if @user.save 
    render json: @user 
    else 
    render @user.errors.full_messages.as_json, status: 400 
    end 
end 

def create_user_params 
    params.require(:user).permit(:email, :phone) 
end 

、その後:あなたの特定のケースでは、私のような何かを書くだろう

class User < ActiveRecord::Base 
    validates_precense_of :some_other #this will cause the user not to save, end thus, report an errer message 
end 
+0

はどうもありがとうございました!! –

1

「Railsの道」。コントローラは、ビジネスロジックに関係なく、セキュリティやホワイトリストのような単純な検証のみを持つことができます。 "Model"はActiveRecord自体だけでなく、特にFormObject https://robots.thoughtbot.com/activemodel-form-objectsのようなもので、リソースの一部がデータベーステーブルに1対1で反映されない場合があります。

あなたが唯一のAPIモードを使用しようとしている場合は、私はあなたが検証メソッドでstrong_parametersの使用は混乱していると思う非常にきちんとしたAPIのDSL https://github.com/ruby-grape/grape#parameter-validation-and-coercion

関連する問題