简体   繁体   中英

My Filterrific filter don't work

I try to implement Filterrific on my application to filter Users. I need to filter by mother_tongue, locality and availability start_time. But it doesn't work. There is no errors but there is no filtering...

Model user.rb :

filterrific(
  default_filter_params: {},
  available_filters: [
    :search_query,
    :search_query,
    :with_start_time_gte
  ]
 )

scope :search_query, lambda { |query|
  return nil  if query.blank?

  terms = query.downcase.split(/\s+/)

  terms = terms.map { |e|
    (e.gsub('*', '%') + '%').gsub(/%+/, '%')
  }
  num_or_conditions = 2
  where(
    terms.map {
      or_clauses = [
          "LOWER(users.mother_tongue) LIKE ?",
          "LOWER(users.locality) LIKE ?"
      ].join(' OR ')
      "(#{ or_clauses })"
    }.join(' AND '),
    *terms.map { |e| [e] * num_or_conditions }.flatten
  )
}

scope :with_start_time_gte, lambda { |ref_date|
  where('availability.start_time >= ?', ref_date)
}

Users_controller.rb :

def index
  @filterrific = initialize_filterrific(
    User,
    params[:filterrific]
    #persistence_id: 'shared_key',
    #default_filter_params: {},
    #available_filters: [],
  ) or return
  @users = @filterrific.find.page(params[:page])

  # Respond to html for initial page load and to js for AJAX filter updates.
  respond_to do |format|
    format.html
    format.js
  end

  rescue ActiveRecord::RecordNotFound => e
    # There is an issue with the persisted param_set. Reset it.
    puts "Had to reset filterrific params: #{ e.message }"
    redirect_to(reset_filterrific_url(format: :html)) and return
end

index.html.erb :

<% provide(:title, 'Liste des utilisateurs') %>
<h1>Liste des utilisateurs :</h1>

<%= form_for_filterrific @filterrific, html: { id: 'filterrific-no-ajax-auto-submit' } do |f| %>
<div>
  Langue :
  <%= f.text_field(
  :search_query,
  class: 'mother_tongue filterrific-periodically-observed'
) %>
</div>
<div>
  Ville :
    <%= f.text_field(
  :search_query,
  class: 'locality filterrific-periodically-observed'
) %>
</div>
<div>
  Date de départ :
    <%= f.text_field(:with_start_time_gte, class: 'js-datepicker') %>
</div>

<%= f.submit 'Rechercher' %>

<div>
  <%= link_to(
   'Reset filters',
  reset_filterrific_url,
) %>
</div>

<%= render_filterrific_spinner %>

_list.html.erb :

<div id="filterrific_results">

<div>
<%= page_entries_info users %>
</div>

<% @users.each do |user| %>
  <h1><%= user.fname %> <%= user.lname %></h1>
    <h2><%= user.mother_tongue %></h2>
  <center>
    <p><%= user.postal_code %> <%= user.locality %></p>

    <p><%= link_to "En savoir plus", user_path(user) %></p>
  </center>
<% end %>

I'm new on rails, so thank you for your help.

The method you used, scope :search_query... , is for finding the input text in one of the 2 database columns you designated, users.mother_tongue and users.locality . Infact the resulting where clause will be "WHERE LOWER(users.mother_tongue) LIKE ? OR LOWER(users.locality) LIKE ?" .

If you want to filter values of 2 fields separatelly, you must define 2 input fields with different names, 2 filters and 2 scopes.

The code could be like this:

Model user.rb :

filterrific(
  default_filter_params: {},
  available_filters: [
    :with_mother_tongue,
    :with_locality,
    :with_start_time_gte
  ]
)

scope :with_mother_tongue, -> (search_string) {
  where("users.mother_tongue ILIKE ?", (search_string.to_s.gsub('*', '%') + '%').gsub(/%+/, '%'))
}

scope :with_locality, -> (search_string) {
  where("users.locality ILIKE ?", (search_string.to_s.gsub('*', '%') + '%').gsub(/%+/, '%'))
}

scope :with_start_time_gte, lambda { |ref_date|
  where('availability.start_time >= ?', ref_date)
}

In the index view you must also render the _list partial (see at the end):

index.html.erb:

<% provide(:title, 'Liste des utilisateurs') %>
<h1>Liste des utilisateurs :</h1>

<%= form_for_filterrific @filterrific, html: { id: 'filterrific-no-ajax-auto-submit' } do |f| %>
<div>
  Langue :
  <%= f.text_field(
  :with_mother_tongue,
  class: 'mother_tongue filterrific-periodically-observed'
) %>
</div>
<div>
  Ville :
    <%= f.text_field(
  :with_locality,
  class: 'locality filterrific-periodically-observed'
) %>
</div>
<div>
  Date de départ :
    <%= f.text_field(:with_start_time_gte, class: 'js-datepicker') %>
</div>

<%= f.submit 'Rechercher' %>

<div>
  <%= link_to(
   'Reset filters',
  reset_filterrific_url,
) %>
</div>

<%= render_filterrific_spinner %>    

#filterrific_results
  = render 'users/list', users: @users

And lastly you have to define the js view called by the index action in the controller when you filter the records filling at least one of the filters input fields:

index.js.erb

<% js = escape_javascript (
  render(partial: 'users/list', locals: {users: @users})
) %>
$("#filterrific_results").html("<%= js %>");

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM