สิ่งที่คุณดูเหมือนจะขาดหายไปคือพารามิเตอร์ default_filter_params
สำหรับมาโครกรองในโมเดล (คำถามของคุณไม่ได้ระบุว่าคุณได้ปรับเปลี่ยนโมเดล VendorLocation เนื่องจากนั่นคือออบเจ็กต์ที่คุณต้องการกรอง นั่นคือสิ่งที่ควรเรียกมาโคร บางทีคุณอาจละเว้นมันออกจากคำถามของคุณ...)
จากเอกสารโมเดล:
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
ซึ่งมีตัวเลือกสำหรับ "select" หรือที่เรียกว่ากล่องดรอปดาวน์ นั่นไม่ใช่สิ่งที่คุณต้องการเลย เว้นแต่ว่าคุณกำลังใช้ตัวกรองแบบดรอปดาวน์) แฮชนี้เก็บเอาไว้ รายการขอบเขตที่จำเป็นต้องใช้ตามค่าเริ่มต้น (คีย์แฮช) และพารามิเตอร์ขอบเขตจะถูกใช้เป็นค่าแฮช
แฮช default_filter_params
นั้นอาจไม่ใช่สิ่งเดียวที่คุณขาดหายไป... คุณต้องกำหนดขอบเขต ActiveRecord เหล่านั้นสำหรับตัวกรองแต่ละตัวที่คุณต้องการใช้ในโมเดล และตั้งชื่อสิ่งเหล่านี้ใน available_filters
ตามด้านบนเพื่อให้พร้อมใช้งานสำหรับตัวกรอง:
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 หรือตัวแปรตำแหน่งใดๆ เลย คุณมีหลายพิกัดสำหรับพารามิเตอร์ตำแหน่งของคุณ แต่คุณไม่ใช่คนแรกที่มีปัญหานี้เลย!
ปัญหานี้ อธิบายได้เกือบจะทุกประการกับปัญหาที่คุณตั้งไว้เพื่อแก้ไข ผู้เขียน Filterrific แนะนำให้ฝังฟิลด์ตำแหน่งลงในฟิลด์ฟอร์มที่ซ่อนอยู่ใน fields_for
ที่ซ้อนกัน เพื่อให้ฟอร์มยังสามารถส่งผ่านอาร์กิวเมนต์เดียวเข้าไปในขอบเขตได้ (ดังเช่นใน 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 %>
... ทำการเปลี่ยนแปลงในมุมมองของคุณ และเพิ่มขอบเขตการจับคู่ที่มีลักษณะดังนี้ (คัดลอกมาจากปัญหา 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 ให้เหมาะสมใน แบบสอบถามเดียวก่อนที่จะส่งผ่านตัวกรองไปยัง Filterrific โดยกำหนดวิธีดัชนีของคอนโทรลเลอร์ของคุณในลักษณะนี้:
def index
@appointments = Appointment.includes(:vendor).
filterrific_find(@filterrific).page(params[:page])
end
หวังว่านี่จะช่วยได้!
person
Kingdon
schedule
01.05.2017