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的图书记录。基本上,应用程序的工作原理是用户可以选择选项并获得与其插入凭证匹配的书籍列表
这些书籍
中的每一本都有类型
,语言
,体裁
每本书可以有几个类型
,语言
和类型
(像一个数组)
MyBooksController
:
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