building a simple search form in Rails?

喜你入骨 提交于 2019-12-19 10:59:08

问题


I'm trying to build a simple search form in Ruby on Rails, my form is simple enough basically you select fields from a series of options and then all the events matching the fields are shown. The problem comes when I leave any field blank.

Here is the code responsible for filtering the parameters

Event.joins(:eventdates).joins(:categories).where
("eventdates.start_date = ? AND city = ? AND categories.name = ?", 
params[:event][:date], params[:event][:city], params[:event][:category]).all

From what I get it's that it looks for events with any empty field, but since all of them have them not empty, it wont match unless all 3 are filled, another problem arises when I try to say, look events inside a range or array of dates, I'm clueless on how to pass multiple days into the search.

I'm pretty new to making search forms in general, so I don't even know if this is the best approach, also I'm trying to keep the searches without the need of a secialized model.


回答1:


Below is probably what you are looking for. (Note: If all fields all blank, it shows all data in the events table linkable with eventdates and categories.)

events = Event.joins(:eventdates).joins(:categories)
if params[:event]
  # includes below where condition to query only if params[:event][:date] has a value
  events = events.where("eventdates.start_date = ?", params[:event][:date]) if params[:event][:date].present?
  # includes below where condition to query only if params[:event][:city] has a value
  events = events.where("city = ?", params[:event][:city]) if params[:event][:city].present?
  # includes below where condition to query only if params[:event][:city] has a value
  events = events.where("categories.name = ?", params[:event][:category]) if params[:event][:category].present?
end

To search using multiple days:

# params[:event][:dates] is expected to be array of dates. 
# Below query gets converted into an 'IN' operation in SQL, something like "where eventdates.start_date IN ['date1', 'date2']"
events = events.where("eventdates.start_date = ?", params[:event][:dates]) if params[:event][:dates].present?



回答2:


It will be more easy and optimised . If you use concern for filter data.

Make one concern in Model.

filterable.rb

module Filterable
  extend ActiveSupport::Concern

  module ClassMethods
    def filter(filtering_params)
     results = self.where(nil)
     filtering_params.each do |key, value|
       if column_type(key) == :date || column_type(key) == 
       :datetime
         results = results.where("DATE(#{column(key)}) = ?", 
         Date.strptime(value, "%m/%d/%Y")) if 
         value.present?  
       else
         results = results.where("#{column(key)} Like ? ", "%#{value}%") if 
         value.present?
       end
     end
     results
    end

   def resource_name
    self.table_name
   end

   def column(key)
    return key if key.split(".").count > 1
    return "#{resource_name}.#{key}"
   end

   def column_type(key)
    self.columns_hash[key].type
   end
  end
end

Include this concern in model file that you want to filter.

Model.rb

 include Filterable

In your controller Add this methods

def search
    @resources = Model.filter(class_search_params)
    render 'index'
end


def class_search_params
    params.slice(:id,:name) #Your field names
end

So, It is global solution. You dont need to use query for filter. just add this concern in your model file. That's it.



来源:https://stackoverflow.com/questions/44816405/building-a-simple-search-form-in-rails

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!