2016-12-24 3 views
3

私はようやく私のようなnoobのために少し複雑ではない場合、私はついに私のfilterrificとその素晴らしい宝石を得ることができました。Filterrificにデフォルトのフィルタを渡す方法

私のオリジナルのインデックス・ページが、このようなユーザに近く、それらに基づいて、アクティブレコードをフィルタリングした

def index 

location_ids = Location.near([session[:latitude], session[:longitude]], 50, order: '').pluck(:id) 
@vendor_locations = VendorLocation.includes(:location).where(location_id: location_ids) 

@appointments = Appointment.includes(:vendor). 
    where(vendor_id: @vendor_locations.select(:vendor_id)) 

end 

だから、これはエリア内のベンダーとの予定のすべてを引き込むが、どのように私はこれを通過しませんFilterrific検索にかけ:

@filterrific = initialize_filterrific(
    params[:filterrific], 
    select_options:{ sorted_by: Appointment.options_for_sorted_by, with_service_id: Service.options_for_select }, 
) or return 

@appointments = @filterrific.find.page(params[:page]) 

respond_to do |format| 
    format.html 
    format.js 
end 

Filterrerrificは、デフォルトですべての予定をロードしているようだが、私は近くのものに限定したいです。私は何が欠けていますか?

答えて

2

あなたが欠けているように見えるのは、モデル内のマクロをフィルタリングするためのパラメータdefault_filter_paramsです。 (あなたの質問には、VendorLocationモデルを調整したことは言及されていませんでした。なぜなら、それはフィルタリングしたいオブジェクトなのでマクロを呼び出す必要があるからです)。

the model docsから:

filterrific(
    default_filter_params: { sorted_by: 'created_at_desc' }, 
    available_filters: [ 
     :sorted_by, 
     :search_query, 
     :with_country_id, 
     :with_created_at_gte 
    ] 
) 

あなたは、おそらく私がいたとき、それが文書の最初のページにあった、しかし、あなたは必要があります(私もこれに走ったサンプルアプリケーションでより重要なものがあります、すでにこれを見つけましたちょうど最近Filterrificを初めて使用しています)。

開始ページの情報はあなたが本当にあなたを始められるのに十分ではありません。 Filterrificをサポートするために、モデル、モデルアクセス、およびビューを変更する必要がある他の方法を確認するには、もう少し読んでください。

効果的なデフォルト設定のフィルタを作る部分は、別名のドロップダウンボックス「選択」するためのオプションを提供し、このdefault_filter_paramsハッシュ(NOT select_options、である。それはあなたがドロップダウンフィルタをやっている場合を除き、あなたが、すべてで欲しいものではありません。 )このハッシュは、デフォルトで適用する必要があるスコープ(ハッシュキー)のリストを保持し、scopeパラメータはハッシュ値として使用されます。

そのうちdefault_filter_paramsハッシュだけでなく、...あなたがモデルで使用する各フィルタのActiveRecordスコープを定義し、上記のようにavailable_filtersに名前を付けて、それらを利用できるようにする必要がありますfilterrific:

scope :with_created_at_gte, lambda { |ref_date| 
    where('created_at >= ?', ref_date) 
end 

それはこれらのスコープは、すべての(引数を取る値はビュー・ページ上のフィルターフィールドの値から来て、あなたは彼らから隠さ維持したい場合でも、あなたのビューにこれらを追加しなければならないことが重要ですユーザー)。常にActiveRecordの関連付けを返すことも重要です。

これは、より多くのあなたが望むもののようである:

scope :location_near, lambda { |location_string| 
    l = Location.near(location_string).pluck(:id) 
    where(location_id: l) 
end 

このアプローチの問題は、あなたのケースでは、何のlocation_stringまたは任意の単一の場所の変数が存在しないということです、あなたがお住まいの地域のパラメータに対して複数の座標を持っています。しかし、あなたはこの問題を最初に持っている人ではありません!

This issueは、解決するために設定した問題をほぼ正確に表しています。Filterrificの作成者は、フォームがまだ(with_distance_fieldsのように)範囲内に単一の引数を渡すことができるように、ネストされたfields_forに隠されたフォームフィールドに位置フィールドを埋め込む推奨:

<%= f.fields_for :with_distance do |with_distance_fields| %> 
    <%= with_distance_fields.hidden_field :lat, value: current_user.lat %> 
    <%= with_distance_fields.hidden_field :lng, value: current_user.lng %> 
    <%= with_distance_fields.select :distance_in_meters, 
    @filterrific.select_options[:with_distance] %> 
<% end %> 

...その変更を行いますあなたのビューで、かつ(リンクGitHubの問題からコピーされた)のようになります一致するスコープを追加します。

scope :with_distance, -> (with_distance_attrs) { 
    ['lng' => '-123', 'lat' => '49', 'distance_in_meters' => '2000'] 
    where(%{ 
    ST_DWithin(
     ST_GeographyFromText(
     'SRID=4326;POINT(' || courses.lng || ' ' || courses.lat || ')' 
    ), 
     ST_GeographyFromText('SRID=4326;POINT(%f %f)'), 
     %d 
    ) 
    } % [with_distance_attrs['lng'], with_distance_attrs['lat'], with_distance_attrs['distance_in_meters']]) 
} 

だから、あなた:with_distance範囲はVendorLocationモデルに行けば、それはおそらく、次のようになります。

scope :with_distance, -> (with_distance_attrs) { 
    lat = with_distance_attrs['lat'] 
    lng = with_distance_attrs['lng'] 
    dist = with_distance_attrs['distance'] 
    location_ids = Location.near([lat, lng], dist, order: '').pluck(:id) 
    where(location_id: location_ids) 
end 

なく、少なくとも最後に、あなたはおそらく、私はあなたが目的であり、それを置く知っincludes(:location) —にお電話を除去したことに気づいた、と私はドキュメントで、それは非常に明確で見つけることができませんでしたが、あなたはまだ得ることができます熱心なロードとActiveRecordのは、このように、コントローラのindexメソッドを定義することにより、Filterrificにフィルタ作業をオフに渡す前に、単一のクエリに最適化があります。このことができます

def index 
    @appointments = Appointment.includes(:vendor). 
    filterrific_find(@filterrific).page(params[:page]) 
end 

希望を!

+0

ドライブバイダウン...なぜこの回答は役に立たなかったのですか? – Kingdon

+1

「.filterrific_find(@filteriffic)」のドキュメントを見つけるのは簡単ではありません。アクティブな関係では、ソースコードから推測しなければなりませんでした。 –

+0

ありがとう! Filterrificは最初は分かりにくいですが、適切に適用する方法を理解すれば本当に強力になりました。これを後で読んで、私がすべてを理解したことに少しショックを与えました。 – Kingdon

関連する問題