2016-08-26 8 views
0

私は、Rails 5 APIを使用してデータを取得するアプリケーションを構築しています。データを抽出するために複数のGETパラメータを使用したいと思います。Rails 5 APIで複数のGETパラメータを管理する

サンプルGETリクエストのフォーマット、単一のパラメータの

/users?company=Samsung&position=Engineer 

コントローラコード: - 複数のパラメータのための

def index 
client = User.where("company = ?", params[:company]) 
render json: client 
end 

コントローラコード: -

def index 
client = User.where("company = ?", params[:company]).where("position = ?", params[:position]) 
render json: client 
end 

同様に/ GETリクエストに含まれていてもいなくてもよい多くのパラメータがあります。ユーザーが任意のパラメータを指定しなかった場合、私は

を欲しい

は、彼はすべてのユーザーを示すべきです。 少数のパラメータしか指定されていない場合は、それらのパラメータのみを検索する必要があります。

ユーザーがGETリクエストにのみ位置パラメータを指定した場合

を何が起こっている、Railsはそれのために指定されたルールがありませんよう&が空白JSONを示し、それを処理することはできません。

多くのパラメータがあり、パラメータの組み合わせごとにルールを書き込むことはできません。

答えて

2

解決策の基本的な問題は、それぞれの場所を順番に実行することです。つまり、会社のパラメータがnilであれば、空のリレーションが得られ、その後のすべてのwhereステートメントは空のリレーションを返します。パラメータが指定されている場合にのみ、条件付きでフィルタリングする必要があります。

クエリ/検索またはフィルタオブジェクト内で実行するのが最も効果的です(クエリはパラメータを取り、結果セットを返し、フィルタはすでに生成されたセットを受け取り、フィルタリングします)。私はにこれらを定義したいと思う人もいますが、app/queriesに入れる人もいます。

ただし、メソッドには矛盾がありますが、インデックスエンドポイントはオブジェクトのリストを返す必要があります。あなたが単一のオプションを取り戻そうとしているとしても、複数のオプションがあると予想する必要があります。インデックスエンドポイントを修正し、フィルタオブジェクトを使用するとします。

# app/controllers/users_controller.rb 
def index 
    users = User.where(1=1) 
    users = Users::Filter.call(users, params) 
    render json: users 
end 

あなたは私はあなたがUser.allを使用する場合は関係するのではなく、配列を返すレール3に対処するために使用してるので、これは、私がUser.where(1=1)を使用気づくでしょう。

# /app/services/users/filter.rb 
class Users::Filter 
    def self.call(resources, options) 
    new(users, options).filter 
    end 

    private 

    attr_reader :resources, :options 

    def initialize(resources, options) 
    @resources = resources 
    @options = options 
    end 

    def filter 
    if options[:company] 
     @resources = resources.where(company: options[:company]) 
    end 

    if options[:position] 
     @resources = resources.where(position: options[:position]) 
    end 

    resources 
    end 
end 

このクラスが誤って使用されないように、私は、プライベートinitializefilterメソッドを呼び出すcallを使用する理由はあります。単一の入力点を持ち、結果セットを返します。これにより、私のフィルタリング機能を変更しやすい小さなバイトサイズのチャンクに分割することもできます。

この例では、私はfilterですべてのフィルタリングを行いましたが、これらのメソッドをブレークアウトして、オブジェクトが応答した場合にフィルタ名を呼び出す巧妙なメタプログラミングを使用することもできます。

EDIT:

ます。また、[1]あなたがオブジェクトに直接パラメータを渡すと、それを検索することができます掻き回すような宝石の解決策を見つける検討することができます。あなたのニーズを満たす検索/フィルタリングの宝石には、さまざまな種類があります。

[1] https://github.com/activerecord-hackery/ransack

関連する問題