代码之家  ›  专栏  ›  技术社区  ›  Rubioli

Ruby on Rails-根据用户选择的选项筛选记录

  •  0
  • Rubioli  · 技术社区  · 6 年前

    在我的申请中,我有一个 Book 模型。我的数据库里有大约10000个图书记录。基本上,应用程序的工作方式是用户可以选择的 选项 并得到一份书单 比赛 他们插入的凭据。

    每一个 books type , language 和; genres .

    每本书可以有几本 类型 , 语言 和; 体裁 (像一个数组)

    title: 'Have fun book' 
    type: ['pdf', 'paper', 'website']
    language: ['Egnlish', 'French', 'German', 'Spanish']
    genres: ['comedy']
    

    我的 BooksController :

    def book_params
      params.require(:book).permit(type:[], language:[], genres:[])
    end
    

    用户可以在其中插入凭证并筛选书籍的表单如下所示:

    Book filter form

    目前,这是我在我的 书商控制器 滤波器 书籍:

    @book_filter = Book
                    .where(type: @book.type)
                    .where(language: @book.language)
                    .where(genres: @book.genres)
    

    这很好,但我有一些问题。例如,如果用户没有选择任何 图书类型/ 类型 或者其他选择,而不是 all 我得到 nil 因此,没有向用户显示任何书籍。

    我想到的是,如果没有选择该选项,那么 where 因为那样的选择不可能 影响 或者它通过 全部的 .

    我没有运气就尝试过:

    @book_filter = Book
                    .where(type: @book.type || '')
                    .where(language: @book.language || '')
                    .where(genres: @book.genres || '')
    

    我的第二个问题是我觉得过滤器可以写得更聪明。 栏杆方式 .

    提前感谢,感谢您的帮助!

    钢轨5.1

    1 回复  |  直到 6 年前
        1
  •  0
  •   Rubioli    6 年前

    在你 models/concerns 创建一个 module :

    module Filterable
      extend ActiveSupport::Concern
    
      module ClassMethods
        def filter(filtering_params)
          results = self.where(nil)
          filtering_params.each do |key, value|
            results = results.public_send(key, value) if value.present?
          end
          results
        end
      end
    end
    

    包括 模块 在你 model 如下:

    class Product
      include Filterable
      ...
    end
    

    然后在控制器中执行以下操作:

    @products = Product.filter(params.slice(:status, :location, :starts_with))
    

    私有的

    # A list of the param names that can be used for filtering the Product list
    def filtering_params(params)
      params.slice(:status, :location, :starts_with)
    end
    

    背后的原因 模块 因为此代码是可重用的,可以在应用程序的任何部分中使用。

    PS:请记住,变量或模型与问题不同,但该解决方案是一个通用的解决方案,可以实现到任何应用程序。