Filterrific gem - Обновление фильтров на основе ассоциаций - PullRequest
0 голосов
/ 14 декабря 2018

В моем приложении у меня есть Country, Region & City.

class Country < ActiveRecord::Base
  has_many :cities
  has_many :regions


class Region < ActiveRecord::Base
  belongs_to :country
  has_many :cities

class City < ActiveRecord::Base
  belongs_to :country
  belongs_to :region

Это моя модель, где у меня есть фильтры

scope :with_country_id, lambda { |country_ids|
  where(:country_id => [*country_ids])
}
delegate :name, to: :country, prefix: true

scope :with_region_id, lambda { |region_ids|
  where(:region_id => [*region_ids])
}
delegate :name, to: :region, prefix: true

scope :with_city_id, lambda { |city_ids|
  where(:city_id => [*city_ids])
}
delegate :name, to: :city, prefix: true

Фильтрсам по себе работает нормально, но могу ли я сделать фильтр, чтобы, когда пользователь выбрал country, мои with_region_id & with_city_id, также обновлялись в зависимости от их ассоциации?

Например, у меня есть страны: США, Великобритания когда пользователь выбирает UK , with_region_id обновляется и отображает только те регионы, которые относятся к UK ,

Anyпомощь приветствуется и спасибо заранее!

1 Ответ

0 голосов
/ 06 января 2019

Я использовал динамическое меню для решения этой проблемы:

Я изменил:

= f.collection_select :with_country_id,@filterrific.select_options[:with_country_id]
= f.collection_select :with_region_id,@filterrific.select_options[:with_region_id]

на:

= f.collection_select :with_country_id, Country.order(:name), :id, :name, {}, { class: 'class'}
= f.grouped_collection_select :with_region_id, Country.order(:name), :regions, :name, :id, :name, include_blank: true

JS:

(function() {
jQuery(function() {
    var regions;

    regions = $('#filterrific_with_region_id').html();

    if($('#filterrific_with_country_id option').is(':selected')){
        var country, escaped_country, options;
        country = $('#filterrific_with_country_id :selected').text();
        escaped_country = country.replace(/([ #;&,.+*~\':"!^$[\]()=>|\/@])/g, '\\$1');
        options = $(regions).filter("optgroup[label='" + escaped_country + "']").html();

        if (options) {
            $('#filterrific_with_region_id').html('<option value="">(Select one)</option>'+options);

        } else {
            $('#filterrific_with_region_id').html('<option value="">Please Select a Country</option>');

        }

        return $('#filterrific_with_country_id').change(function() {
            var country, escaped_country, options;
            country = $('#filterrific_with_country_id :selected').text();
            escaped_country = country.replace(/([ #;&,.+*~\':"!^$[\]()=>|\/@])/g, '\\$1');
            console.log(escaped_country);
            options = $(regions).filter("optgroup[label='" + escaped_country + "']").html();
            if (options) {
                $('#filterrific_with_region_id').html('<option value="">(Select one)</option>'+options);

            } else {
                $('#filterrific_with_region_id').html('<option value="">Please Select a Country</option>');

            }
        });


    } else {
        console.warn('NOT SELECTED');

        return $('#filterrific_with_country_id').change(function() {
            var country, escaped_country, options;
            country = $('#filterrific_with_country_id :selected').text();
            escaped_country = country.replace(/([ #;&,.+*~\':"!^$[\]()=>|\/@])/g, '\\$1');
            console.log(escaped_country);
            options = $(regions).filter("optgroup[label='" + escaped_country + "']").html();
            if (options) {
                $('#filterrific_with_region_id').html('<option value="">(Select one)</option>'+options);

            } else {
                $('#filterrific_with_region_id').html('<option value="">Please Select a Country</option>');

            }
        });
    }

});
...