Apa yang tampaknya Anda lewatkan adalah param default_filter_params
untuk memfilter makro yang bagus dalam model. (Pertanyaan Anda tidak menyebutkan bahwa Anda melakukan penyesuaian apa pun pada model VendorLocation, karena itulah objek yang ingin Anda filter, di situlah makro harus dipanggil. Mungkin Anda baru saja menghilangkannya dari pertanyaan Anda...)
Dari dokumen model:
filterrific(
default_filter_params: { sorted_by: 'created_at_desc' },
available_filters: [
:sorted_by,
:search_query,
:with_country_id,
:with_created_at_gte
]
)
Anda mungkin sudah menemukannya, itu ada di halaman pertama dokumentasi, tetapi ada hal yang lebih penting dalam contoh aplikasi yang Anda perlukan (Saya juga mengalami ini, ketika saya baru saja menggunakan Filterrific untuk pertama kalinya.)
Informasi di halaman awal tidak cukup untuk membantu Anda memulai. Anda harus membaca lebih jauh untuk melihat cara lain yang mungkin Anda perlukan untuk mengubah model, akses model, dan tampilan untuk mendukung Filterrific.
Bagian yang membuat pengaturan filter default efektif adalah hash default_filter_params
ini (BUKAN select_options
, yang menyediakan opsi untuk "pilih" alias kotak dropdown. Itu bukan yang Anda inginkan sama sekali, kecuali Anda melakukan filter dropdown.) Hash ini berlaku daftar cakupan yang perlu diterapkan secara default (kunci hash) dan parameter cakupan digunakan sebagai nilai hash.
Hash default_filter_params
itu mungkin bukan satu-satunya hal yang Anda lewatkan... Anda juga harus mendefinisikan cakupan ActiveRecord tersebut untuk setiap filter yang ingin Anda gunakan dalam model, dan beri nama ini dalam available_filters
seperti di atas agar tersedia untuk filterrific:
scope :with_created_at_gte, lambda { |ref_date|
where('created_at >= ?', ref_date)
end
Semua cakupan ini harus mengambil argumen (nilai berasal dari nilai bidang filter pada halaman tampilan, Anda harus menambahkan ini ke tampilan meskipun Anda ingin menyembunyikannya dari pengguna). Penting juga agar mereka selalu mengembalikan asosiasi ActiveRecord.
Ini lebih seperti yang Anda inginkan:
scope :location_near, lambda { |location_string|
l = Location.near(location_string).pluck(:id)
where(location_id: l)
end
Masalah dengan pendekatan ini adalah dalam kasus Anda, tidak ada location_string atau variabel lokasi tunggal apa pun, Anda memiliki banyak koordinat untuk parameter lokasi Anda. Namun Anda bukanlah orang pertama yang mengalami masalah ini!
Masalah ini menjelaskan hampir persis masalah yang ingin Anda selesaikan. Penulis Filterrific merekomendasikan untuk menyematkan bidang lokasi ke dalam bidang formulir tersembunyi di fields_for
yang disarangkan, sehingga formulir tersebut masih dapat meneruskan satu argumen ke dalam cakupan (seperti dalam with_distance_fields
):
<%= 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 %>
... buat perubahan itu di tampilan Anda, dan tambahkan cakupan pencocokan yang terlihat seperti (disalin dari masalah GitHub tertaut):
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']])
}
Jadi, cakupan Anda :with_distance
harus masuk ke model VendorLocation
dan mungkin akan terlihat seperti ini:
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
Terakhir, Anda mungkin memperhatikan bahwa saya menghapus panggilan Anda ke includes(:location)
Saya tahu Anda sengaja meletakkannya di sana, dan saya tidak menemukannya dengan jelas di dokumentasi, tetapi Anda masih bisa bersemangat memuat dan mengoptimalkan ActiveRecord ke dalam kueri tunggal sebelum meneruskan filter berfungsi ke Filterrific dengan mendefinisikan metode indeks pengontrol Anda dengan cara ini:
def index
@appointments = Appointment.includes(:vendor).
filterrific_find(@filterrific).page(params[:page])
end
Semoga ini membantu!
person
Kingdon
schedule
01.05.2017