Кажется, вам не хватает параметра 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
(НЕ select_options
, который предоставляет параметры для «выбора», также известного как раскрывающиеся списки. Это совсем не то, что вам нужно, если только вы не используете раскрывающийся фильтр.) Этот хеш содержит список областей, которые должны быть применены по умолчанию (ключи хеш-функции), а параметр области используется в качестве значения хеш-функции.
Этот хэш 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 или какой-либо одной переменной местоположения, у вас есть несколько координат для параметров вашего местоположения. Но вы вообще не первый человек с такой проблемой!
Эта проблема почти точно описывает проблему, которую вы намеревались решить. Автор 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