在rails中查询belongs_to关系时如何使用通配符



我有一个搜索/筛选表单,用户可以从中选择一个到多个参数来筛选记录。过滤器可以包括特定的user_id、company_id或project_id等。这些参数的任何组合都可以由.提交给过滤器记录

我要做的是创建尽可能简单的查询,而不需要重新查询子集。

我可以通过在查询中使用更多的逻辑来实现这一点。。。但是,似乎应该有一条铁路。

Thing.where( params[:user_id].present? ? user_id: params[:user_id] : "user_id IS NOT NULL" ).
where( params[:company_id].present? ? company_id: params[:company_id] : "company_id IS NOT NULL" )

我追求的是更干净的东西。。。类似:

Thing.where( user_id: params.fetch(:user_id, '*') )

然后,我可以像这样链接所有可用的搜索参数:

Thing.where(
user_id: params.fetch(:user_id, '*'),
company_id: params.fetch(:company_id, '*'),
project_id: params.fetch(:project_id, '*')
)

另一种方法

Things.在哪里(''(将返回所有Things。所以,我可以做一些类似的事情:

Thing.where( params[:user_id].present? ? { user_id: params[:user_id] } : '' )

但是,这似乎不像轨道。

有办法做到这一点吗?谢谢

只需创建一个以参数为输入并创建范围的模型:

class ThingFilter
include ActiveModel::Model
include ActiveModel::Attributes
attribute :user_id
attribute :company_id
attribute :project_id
def resolve(scope = Thing.all)
attributes.inject(scope) do |filtered, (attr_name, value)|
if !value.present? 
scope.merge(Thing.where.not(attr_name => nil))
else
scope.merge(Thing.where(attr_name => value))
end
end
end
end
class Thing < ApplicationRecord
def self.filter(**kwargs)
ThingFilter.new(**kwargs).resolve(self.where)
end
end
@things = Thing.filter(
params.permit(:user_id, :company_id, :project_id)
)

这非常容易测试,如果需要,可以添加验证等功能,而不会弄乱控制器。您也可以将其绑定到表单。

在这种情况下可以使用一个名为#merge的方法。

@things = Thing.all
@things = @things.merge(-> { where(user_id: params[:user_id]) }) if params[:user_id].present?
@things = @things.merge(-> { where(company_id: params[:company_id]) }) if params[:company_id].present?
@things = @things.merge(-> { where(project_id: params[:project_id]) }) if params[:project_id].present?

虽然这不是最简洁的方法,但在我看来,它可读性很强。


找到了一种简洁的方法,但要根据您对可读性的看法使用它。

@things =
params.slice(:user_id, :company_id, :project_id).
reduce(Thing.all) do |relation, (column, value)|
relation.where(column => value)
end

感觉您可能正在对Ransack gem已经提供的内容进行编码。

它接受搜索参数,如user_id_eqcompany_name_present,以及排序参数,并将它们转换为所需的SQL。

https://github.com/activerecord-hackery/ransack

相关内容

  • 没有找到相关文章

最新更新