2013-05-17 15 views
6

私はこれを一日中考えようとしていて、それは私を狂わせてしまいます。彼女のファラデーを使ったAPIでのページ設定のレール

私は2つのレールアプリ、ServerAppとClientAppを持っています。 ClientAppは、彼女のgemを使用して、ServerAppからAPIを介してデータを取得します。ページングの情報が必要になるまで、すべてが素晴らしかったです。

これは(これはページネーションのためkamainariを使用し、検索のために掻き回す)私が注文を取得するために使用しています方法です:

# ServerApp 
def search 
    @search = Order.includes(:documents, :client).order('id desc').search(params[:q]) 
    @orders = @search.result(distinct: true).page(params[:page]).per(params[:per]) 

    respond_with @orders.as_json(include: :documents) 
end 

それは彼女がのコレクションとして使用するJSONでハッシュの配列を返します注文。それはうまく動作します。

# Response 
[ 
    { 
    "client_id": 239, 
    "created_at": "2013-05-15T15:37:03-07:00", 
    "id": 2422, 
    "ordered_at": "2013-05-15T15:37:03-07:00", 
    "origin": "online", 
    "updated_at": "2013-05-15T15:37:03-07:00", 
    "documents": [ 
     { ... } 
    ] 
    }, 
    ... 
] 

しかし、ページング情報が必要でした。それは私がsend it as metadata with my jsonに必要なように見えた。だから私は、これまでの私の応答を変更します。

respond_to do |format| 
    format.json do 
    render json: { orders: @orders.as_json(include: :documents), metadata: 'sent' } 
    end 
end 

私ClientAppに私はorders.metadata @書くことができますし、「送信され」ますので、これは確かに、メタデータを介して送信ありません。しかし今、私の注文は「注文」内の配列に入れ子になっていますので、@ orders.ordersを使う必要があり、それを彼女のコレクションではなく配列のように扱います。

いくつかの読書をした後、ヘッダーを介してページ番号情報を送信することは、他の多くの人がこれをやったやり方でした(私はthis guideを使ってafter_filterでヘッダーを設定することができました)。しかし、ClientAppでこれらの応答ヘッダーを取得する方法については、さらに迷っています。ファラデーミドルウェアが必要だと思っていますが、これを稼働させるのは幸運なことです。

私はこれをどうやってやればいいか知っていれば、とても感謝しています。私はこれで壁に頭を打つ別の日を取ることができませんが、私はちょうどのような感じの1つの重要な情報を離れてこれを解決するからです!

+0

EVT

は、ここでは、コードです。これは彼女のプロジェクトの問題かもしれません。そこに問題を開いて、プロジェクトの保守担当者からのフィードバックがあるかどうかを確認できます。 – poseid

+0

私は彼女のgithubページに投稿することを検討していましたが、私はこれが私のところではもっと誤解であり、 – d3vkit

答えて

6

同じ問題が発生し、私自身のミドルウェアを追加し、 "parse"と "on_complete"メソッドをそれほどの手間とグローバル変数の使用を避けて書き直すことで解決しました。次のように

class CustomParserMiddleware < Her::Middleware::DefaultParseJSON 
     def parse(env) 
     json = parse_json(env[:body]) 
     pagination = parse_json(env[:response_headers][:pagination_key]) || {} 
     errors = json.delete(:errors) || {} 
     metadata = json.delete(:metadata) || {} 
     { 
      :data => json, 
      :errors => errors, 
      :metadata => { 
       :pagination => pagination, 
       :additional_metadata => metadata 
      }, 

    end 

     def on_complete(env) 
     env[:body] = case env[:status] 
      when 204 
      parse('{}') 
      else 
      parse(env) 
     end 
     end 
    end 

そして、あなたが改ページにアクセスすることができます:

model = Model.all 
    model.metadata[:pagination] 
0
  • 接続を設定するときは、時にはそれは、ESP、最初curl要求を行うのに役立ちますhttp://rubydoc.info/gems/faraday/0.8.7/Faraday/Connection:initialize

  • でドキュメントを参照して、ファラデーにヘッダオプションを渡すことができます。すべてのヘッダーが表示される詳細出力には-vvオプションを使用してください。 (サーバーからのログ出力を添付することもできます)

  • cloggerhttp://clogger.rubyforge.org/は)私が最終的にこの作業を得たRailsのサーバ側

+0

私は実際に彼女のgithubページに掲載されているミドルウェアを使ってファラデーにヘッダを追加しています。問題は、APIから返されたヘッダーを取得するためにon_completeミドルウェアを作成する方法を完全に理解していないことです。私はPostman Chrome拡張機能を使用していますが、ヘッダーはそこにあります - 私はちょうどそれらを使用する方法がわかりません!私が一番遠いところには、ログに書き込むだけのヘッダーを使って何をすべきかを説明するガイドがあります。 – d3vkit

2

のヘッダ情報を監視しません。そのトリックはファラデーでグローバル変数を使用することでしたon_complete - 私はより良い解決策を見つけることを試みましたが、これは私ができる最高でした。もう一度、私はhereからヘッダーコードを得ました。彼女と一緒に仕事をする方法の完全なガイドは次のとおりです:

私のサーバー側では、私はカミナリの宝石を持っており、クライアントからサーバにパラメタとしてpageperを渡します。戻るサーバー上の

@orders = Order.search(q: { client_id_eq: @current_user.id }, page: params[:page], per: 3)` 

、私は私のApiControllerに(APIのアプリコントローラ)、これを持っている:(これも検索する掻き回すを使用している)

def search 
    @search = Order.order('id desc').search(params[:q]) 
    @orders = @search.result(distinct: true).page(params[:page]).per(params[:per]) 

    respond_with @orders.as_json(include: :items) 
end 

私のクライアントは、そのような要求を行い

サーバorders_controller.rbで
protected 
    def self.set_pagination_headers(name, options = {}) 
    after_filter(options) do |controller| 
     results = instance_variable_get("@#{name}") 
     headers["X-Pagination"] = { 
     total_count: results.total_count, 
     offset_value: results.offset_value 
     }.to_json 
    end 
    end 

、私は、検索方法のための改ページヘッダーを設定:

class OrdersController < ApiController 
    set_pagination_headers :orders, only: [:search] 
    ... 
end 

ここでヘッダーを受け取るには、クライアントの彼女のファラデーミドルウェアが必要です。

# config/initializers/her.rb 
Her::API.setup url: Constants.api.url do |c| 
    c.use TokenAuthentication 
    c.use HeaderParser # <= This is my middleware for headers 
    c.use Faraday::Request::UrlEncoded 
    c.use Her::Middleware::DefaultParseJSON 
    c.use Faraday::Adapter::NetHttp 
    c.use Faraday::Response::RaiseError 
end 

# lib/header_parser.rb 
# don't forget to load this file in application.rb with something like: 
# config.autoload_paths += Dir[File.join(Rails.root, "lib", "*.rb")].each { |l| require l } 

class HeaderParser < Faraday::Response::Middleware 
    def on_complete(env) 
    unless env[:response_headers]['x-pagination'].nil? 
     # Set the global var for pagination 
     $pagination = JSON.parse(env[:response_headers]['x-pagination'], symbolize_names: true) 
    end 
    end 
end 

クライアントコントローラに戻ると、$ paginationというグローバル変数があります。鉱山は次のようになります。私は、これは他の誰かを助けることができると思います

@orders = Kaminari.paginate_array(@orders, total_count: $pagination[:total_count]).page(params[:page]).per(params[:per_page])` 

、及び場合:

$pagintation = { total_count: 0, offset_value: 0 }` 

は最後に、私は配列をページ分割し、それらの容易な改ページのリンクを得るために、私のクライアントアプリに雷宝石を追加しました誰もがこれを行うためのより良い方法を知って、私に教えて!

関連する問題