这是我的众多过滤器之一:
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中的类别(所有这些)
在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
这将为我提供生成Grid并传递给视图的范围。
现在我需要让过滤器仅显示该用户的已售出类别。
我需要做的就是以某种方式将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
)中扩展它时,我得到一些方法的未定义错误。这是因为我的身份验证模块还有很多来自其他模块的其他方法,比如Devise和Declarative Authorization。所以我不认为延伸将是一个选择。
提前致谢
编辑:
在控制器中:
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
一切正常。
干杯。
答案 0 :(得分:2)
您可以将任何对象传递给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
方法将默认值添加到哈希,如上例所示。