【问题标题】:building a simple search form in Rails?在 Rails 中构建一个简单的搜索表单?
【发布时间】:2017-12-02 15:21:13
【问题描述】:

我正在尝试在 Ruby on Rails 中构建一个简单的搜索表单,我的表单很简单,基本上你从一系列选项中选择字段,然后显示与这些字段匹配的所有事件。当我将任何字段留空时,问题就来了。

这里是负责过滤参数的代码

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

据我所知,它会查找具有任何空字段的事件,但由于它们都不是空的,除非所有 3 个都被填充,否则它不会匹配,当我试图说时出现另一个问题,看看里面的事件日期范围或数组,我不知道如何将多天传递到搜索中。

一般来说,我对制作搜索表单还很陌生,所以我什至不知道这是否是最好的方法,而且我正在尝试在不需要专门模型的情况下保留搜索。

【问题讨论】:

    标签: ruby-on-rails ruby search activerecord rails-activerecord


    【解决方案1】:

    以下可能是您要查找的内容。 (注意:如果所有字段都为空,则显示事件表中的所有数据,可与事件日期和类别链接。)

    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
    

    使用多天搜索:

    # 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?
    

    【讨论】:

    • 这个真的很好,但是我会坚持一段时间,直到我得到下面的答案完全实现,但这个更容易理解。
    • @events.all.distinct.each 使得所有事件都被列出一次,如果它们有多个类别。
    【解决方案2】:

    会更加简单和优化。如果您对过滤数据使用关注。

    在模型中提出一个问题。

    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
    

    将此问题包含在您要过滤的模型文件中。

    模型.rb

     include Filterable
    

    在你的控制器中添加这个方法

    def search
        @resources = Model.filter(class_search_params)
        render 'index'
    end
    
    
    def class_search_params
        params.slice(:id,:name) #Your field names
    end
    

    所以,它是全球解决方案。您不需要使用查询进行过滤。只需在您的模型文件中添加这个问题。 就是这样。

    【讨论】:

    • 我在实现这个解决方案时遇到了问题,无论我通过搜索方法发送的输入如何,它都会返回所有可能的事件,即使留空,即使我的表单像 f.text_field :name 一样简单,所以我不知道我做错了什么。
    • @Bluespheal 你做了搜索路线吗?如果是,则将 exit 放入 filter 方法中。你可以在那里扔垃圾。你的关键和价值是什么。关键和价值是最重要的。 !如果您仍然遇到问题,请告诉我。
    • 是的,我有搜索路线和索引视图,问题是列出了所有可能的事件我既没有看到键也没有看到值,我看到的唯一参数是city: , date: and category: all inside event 也许我遗漏了什么,最让我困惑的是如何处理 key 和 value。
    • @Bluespheal 键是您要过滤的字段名称,值是您输入搜索的字段的值。例如您在文本字段名称中输入“test”并搜索它..然后名称成为键,值成为测试。明白了吗?
    • 哦!现在我明白了,我仍然无法过滤值date: '2017-06-30'city: Tulumcategory: Cultura 被传递,但所有事件都使用@resources.each do |event| 列出我觉得我错过了一些明显的东西......
    猜你喜欢
    • 1970-01-01
    • 2023-03-11
    • 1970-01-01
    • 2015-07-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-11
    相关资源
    最近更新 更多