jhund / filterrific

Filterrific is a Rails Engine plugin that makes it easy to filter, search, and sort your ActiveRecord lists.
http://filterrific.clearcove.ca
MIT License
912 stars 125 forks source link

Multi-select not working. Unpermitted parameter shows. #113

Open patrocc6 opened 7 years ago

patrocc6 commented 7 years ago

I am trying to get multi-select working using the chosen jquery plugin. When using a single select box everything works as expected. When changing to allow for multiple selections, filtering breaks and I get an unpermitted parameter warning in the console for the "with_state" parameter.

Using rails 5.0 & filterrific 2.0

Model

scope :with_state, lambda { |states|
    where(state: [*states])
  }

filterrific(
    default_filter_params: { sorted_by: 'name_asc' },
    available_filters: [
      :sorted_by,
      :search,
      :is_private,
      :size_is,
      :with_state
    ]
  )

Controller

def index
    @filterrific = initialize_filterrific(
      School,
      params[:filterrific],
      select_options: {
        with_state: School.options_for_states
      }
    ) or return

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

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

View

<%= f.select(
        :with_state,
        @filterrific.select_options[:with_state],
        { include_blank: '', include_hidden: false },
        {
          class: "form-control chosen-select",
          multiple: true, #this line is what breaks it
          "data-placeholder" => "Choose a state..."
        }
      ) %>

Console

Processing by SchoolsController#index as JS
  Parameters: {"utf8"=>"✓", "filterrific"=>{"search"=>"", "size_is"=>"", "is_private"=>"", "with_state"=>["NY"]}, "_"=>"1479566468618"}
  Rendering schools/index.js.erb
Unpermitted parameter: with_state
patrocc6 commented 7 years ago

It looks like the problem is coming from the way the parameters are being permitted in param_set.rb

filterrific_params = filterrific_params.permit(model_class.filterrific_available_filters).to_h.stringify_keys

This line permits the available filters but does not take into account the nested array parameters created by a multiple selection. For now I am working around this issue by explicitly permitting my parameters in param_set.rb

filterrific_params = filterrific_params.permit(["is_private", "search", "size_is", "sorted_by", "with_state" => []]).to_h.stringify_keys
patrocc6 commented 7 years ago

Updated the initialize method to be able to properly permit parameters with arrays or hashes. Went off of pull request #115 which fixes another issue with permitting parameters #114

    def initialize(a_model_class, filterrific_params = {})
      self.model_class = a_model_class
      @select_options = {}

      # Use either passed in filterrific_params or resource class' default_settings.
      # Don't merge the hashes. This causes trouble if an option is set to nil
      # by the user, then it will be overriden by default_settings.
      # You might wonder "what if I want to change only one thing from the defaults?"
      # Persistence, baby. By the time you submit changes to one filter, all the others
      # will be already initialized with the defaults.
      filterrific_params = model_class.filterrific_default_filter_params  if filterrific_params.blank?
      if defined?(ActionController::Parameters) && filterrific_params.is_a?(ActionController::Parameters)
        permissible_filter_params = []
        model_class.filterrific_available_filters.each do |p|
          if filterrific_params[p].is_a?(Hash)
            permissible_filter_params << { p => filterrific_params[p].keys }
          elsif filterrific_params[p].is_a?(Array)
            permissible_filter_params << { p => [] }
          else
            permissible_filter_params << p
          end
        end
        filterrific_params = filterrific_params.permit(permissible_filter_params).to_h.stringify_keys
      else
        filterrific_params.stringify_keys!
      end
      filterrific_params = condition_filterrific_params(filterrific_params)
      define_and_assign_attr_accessors_for_each_filter(filterrific_params)
    end
nkabbara commented 7 years ago

Thanks for this Pat. Helped a lot.

blaedj commented 7 years ago

Thanks Pat. I turned the above code into a PR for #115 (see https://github.com/ayaman/filterrific/pull/2), so hopefully both are merged soon!

januszm commented 7 years ago

This hasn't been released to RubyGems yet right? It seems like now it is impossible to use 'array' parameters, like for range sliders or multiple selects, because they are not permitted.

vzelenko commented 7 years ago

When will this be released?

acrolink commented 6 years ago

Kindly release a new updated release including this patch, I had to use master branch in order to fix this issue. Thank you.