如何根据rails的当前作用域修改数据网格上的过滤器



这是我众多滤镜中的一个:

 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,就像上面的例子一样。

最新更新