Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/53.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/solr/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails RubyonRails-根据用户选择的选项过滤记录_Ruby On Rails_Filter_Rails Activerecord - Fatal编程技术网

Ruby on rails RubyonRails-根据用户选择的选项过滤记录

Ruby on rails RubyonRails-根据用户选择的选项过滤记录,ruby-on-rails,filter,rails-activerecord,Ruby On Rails,Filter,Rails Activerecord,在我的应用程序中,我有一本书模型。我的数据库中有大约10000k的图书记录。基本上,应用程序的工作原理是用户可以选择选项并获得与其插入凭证匹配的书籍列表 这些书籍中的每一本都有类型,语言,体裁 每本书可以有几个类型,语言和类型(像一个数组) MyBooksController: def book_params params.require(:book).permit(type:[], language:[], genres:[]) end 用户可以在其中插入凭据并筛选书籍的表单如下图所示:

在我的应用程序中,我有一本
模型。我的数据库中有大约10000k的图书记录。基本上,应用程序的工作原理是用户可以选择选项并获得与其插入凭证匹配的书籍列表

这些
书籍
中的每一本都有
类型
语言
体裁

每本书可以有几个
类型
语言
类型
(像一个数组)

My
BooksController

def book_params
  params.require(:book).permit(type:[], language:[], genres:[])
end
用户可以在其中插入凭据并筛选书籍的表单如下图所示:

目前,这就是我在我的
BooksController
中过滤书籍的步骤:

@book_filter = Book
                .where(type: @book.type)
                .where(language: @book.language)
                .where(genres: @book.genres)
这很好,但我有一些问题。例如,如果用户没有选择任何书籍类型/
类型
或任何其他选项,而不是获取
全部
,则我得到
,因此,不会向用户显示任何书籍

我想的是,如果没有选择该选项,则该选项的
where
不会受到影响,或者它会通过
所有

我尝试了这个,但没有成功:

@book_filter = Book
                .where(type: @book.type || '')
                .where(language: @book.language || '')
                .where(genres: @book.genres || '')
我的第二个问题是,我觉得过滤器可以写得更智能&Rails方式

提前感谢,感谢您的帮助


Rails 5.1在您的
模型/关注点中创建
模块

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
在您的
型号中包括
模块
,如下所示:

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:请记住变量或模型与问题不同,但解决方案是一个通用的解决方案,可以应用于任何应用程序。

基于但替换
public\u send
,用于
我工作的地方。轨道5

module Filterable
  extend ActiveSupport::Concern

  module ClassMethods
    def filter(filtering_params)
      results = self.where(nil)
      filtering_params.each do |key, value|
        results = results.where("#{key} = ?", value) if value.present?
      end
      results
    end
  end
end

将筛选器移动到变量
@book\u filter=book.all
,然后相应地进行筛选:
@book\u filter=@book\u filter.where(type:@book.type)if@book.type.present?
等。顺便问一下,您如何存储类型和语言?您是否正在使用
PostgreSQL
中的
array
字段?谢谢@RocKhalil如果我只选中
@book.type
,这可能会起作用,但还有其他一些字段,如语言、泛型和2-3个,我想这就是为什么我不能只使用
@book\u过滤器的原因。where(type:@book.type)如果@book.type.present?
,因为在那里也会有其他的
和条件。是的,我使用数组存储它们是的,你必须这样做:
@book\u filter=@book\u filter.where(type:@book.type)if@book.type.present?
@book\u filter=@book\u filter.where(language:@book.language)if@book.language.present?
@book\u filter=@book\u filter.where(genres:@book.genres)如果@book.genres.present?
;我还建议将它们转移到模型中(
类型
语言
类型
),并具有
多对多
关系;这就是你要问的
Rails方式
:-pThanks@RocKhalil。我认为这在某种程度上是可行的,但不是我认为的Rails方式:P将它们移动到模型也可能是一种选择,但这需要额外的“东西”,我认为这里不需要这些东西:P因为与一本书相比,它将有超过6-7个表,并且都与
多对多
相连接。我认为这太过分了
module Filterable
  extend ActiveSupport::Concern

  module ClassMethods
    def filter(filtering_params)
      results = self.where(nil)
      filtering_params.each do |key, value|
        results = results.where("#{key} = ?", value) if value.present?
      end
      results
    end
  end
end