这是我众多滤镜中的一个:
filter(:item_id, :enum,
:header => "Category",
:select => lambda { scope.select(" distinct(category.title), transactions.item_id ").map {|p| [p.title, p.item_id]}},
:multiple => false,
:include_blank => true
) do |value|
self.where(:items => { :id => value } )
end
正如你所看到的,它正在从DB(所有的)调用Category
在我的SalesReportController的报告中,我有这个:
def index
user_acls = find_current_user_acls
@grid = SalesReportsGrid.new(params[:sales_reports_grid]) do |scope|
scope.where("access_lists.id" => user_acls).page(params[:page])
end
@grid.assets
end
这将给我的范围,生成网格和传递给视图。
现在我需要使过滤器只显示该用户销售的类别。
我所要做的就是把user_acls
传递给SalesReportsGrid
类
如果我可以通过user_acls
,那么我可以这样做:
filter(:item_id, :enum,
:header => "Category",
:select => lambda { scope.select(" distinct(category.title), transactions.item_id ").where("access_lists.id" => user_acls).map {|p| [p.title, p.item_id]}},
:multiple => false,
:include_blank => true
) do |value|
self.where(:items => { :id => value } )
end
快速解释:
例如:User1为座席她卖出了4个类别的100件商品。她转到报告页。目前,基于上面的代码,我只向她展示了她自己销售的商品,但是过滤器下拉列表包含了数据库中的所有类别,这是没有意义的。
不幸的是,我的ACL模块有点粒度,当我尝试在SalesReportsGrid
(sales_reports_grid.rb
)扩展它时,我得到一些方法的未定义错误。这是因为我的身份验证模块有许多来自其他模块的其他方法,如设计和声明式授权。所以我不认为扩展会是一个选择。提前感谢
:
def index
# This will return an array of ACL ids for the user
user_acls = find_current_user_acls
@grid = SalesReportsGrid.new(params[:sales_reports_grid].merge(user_acls: user_acls)) do |scope|
scope.where("access_lists.id" => user_acls).page(params[:page])
end
@grid.assets
end
旁边的错误我得到关于:undefined method merge for nil:NilClass
params[:sales_reports_grid]
中没有任何内容,这就是为什么我得到错误。
SalesReportsGrid.new(user_acls: user_acls )
时,我得到了结果。我猜这是我的ActiveRecord的限制:(
我已经在SalesGrid attr_accessor :user_acls
中添加了这个
所有工作伙伴:
你能解释一下这一点,因为我不能理解它:当我补充到::select => lambda { scope.select(" distinct(categories.title), transactions.item_id ").where("access_lists.id" => :user_acls).map {|p| [p.title, p.item_id]} }
:user_acls
值从未返回,但是当我这样做:
def categories_select
scope.select(" distinct(category.title), transactions.item_id ").where("access_lists.id" => user_acls).map {|p| [p.title, p.item_id]}
end
和添加:select => :categories_select
都可以正常工作。
欢呼。
您可以将任何对象传递给Datagrid对象。
例如current_user, ALC对象或可访问类别。
那么在你的情况下,解决方案看起来像:
class SalesReportsGrid
scope { ... }
attr_accessor :user_ucls
filter(:item_id, :enum, select: :categories_select, ...) do
...
end
def categories_select
scope.select(" distinct(category.title), transactions.item_id ").where("access_lists.id" => user_acls).map {|p| [p.title, p.item_id]}
end
end
SalesReportsGrid.new(params.fetch(:sales_reports_grid, {}).merge(user_acls: user_acls))
请注意,为了从select
选项访问网格对象数据,您需要将其提取到一个方法中。
您提到的错误是由Nil类限制产生的:nil.merge({})
。为了避免这种情况,使用fetch
方法将默认值添加到Hash,就像上面的例子一样。