ActiveAdmin - 组合范围和过滤器

时间:2015-04-11 23:08:24

标签: ruby-on-rails filter scope activeadmin

我有一个ActiveAdmin实例,我User has_many Thing。我还希望允许用户通过使用User模型与其他Thing关联,使用自引用has_many来充当其他User Employments的管理员。模型看起来像这样......

class User < ActiveRecord::Base
    ...

    has_many :things, dependent: :destroy


    has_many :employments, foreign_key: 'employer_id', dependent: :destroy
    has_many :employees, through: :employments
    has_many :inverse_employments, class_name: 'Employment', foreign_key: 
                  'employee_id', dependent: :destroy
   has_many :employers, through: :inverse_employments

   accepts_nested_attributes_for :employments, allow_destroy: true

   ...
end

class Employments < ActiveRecord::Base
    belongs_to :employer, :class_name => 'User'
    belongs_to :employee, :class_name => 'User'

    # Also has other metadata attributes
end

class Thing < ActiveRecord::Base
    belongs_to :user
end

在ActiveAdmin中,我希望用户能够管理自己的东西以及其他用户的东西。我已经设置了范围和过滤器,如下所示

ActiveAdmin.register Thing do
    ...

    scope_to :current_user

    scope 'Owned', :all, default: true do
      Rezzable::Pinger.where(user_id: current_user.id)
    end

    scope :managed do
      Rezzable::Pinger.where(user_id: Employment.where(employee_id: 
          current_user.id).collect{ |e| e.employer_id })
    end
end

范围很有效,但过滤器不起作用。如果我删除范围,过滤器工作正常。我还致力于创建一个仅显示托管或拥有项目的过滤器,但由于拥有的东西的关联是直接的,因此对该关联的洗劫也证明是困难的,但另一个必须通过雇佣和获得雇主的事情来完成。

有没有办法让范围和过滤器很好地协同工作?如果做不到这个,有没有其他可能更好的方法来实现这一目标?提前谢谢。

PS - 我确实认为这与ActiveAdmin - Using scopes with filters的问题相同,但我不认为这个解决方案对我有用,因为我们的关联非常不同。

1 个答案:

答案 0 :(得分:0)

emI找到了一个可行的解决方案,尽管它并没有真正解决混合范围和过滤器的问题。

我没有创建 托管的 范围,而是创建了一个新的命名空间

配置/初始化/ active_admin.rb

config.namespace :my do |my|
  my.authentication_method = :authenticate_user!
  my.current_user_method = :current_user
  my.build_menu :utility_navigation do |menu|
    menu.add label: proc{ "#{display_name current_user.name} - My Stuff" },
           url: proc { my_dashboard_path },
           id: 'current_user',
           priority: 1,
           if: proc { current_user.can_be_user? }
    menu.add label: 'Admin Dashboard',
           url: proc { admin_dashboard_path },
           if: proc { current_user.can_be_admin? }
    menu.add label: 'Manager Dashboard',
           url: proc { manager_dashboard_path },
           if: proc { current_user.employers.size > 0 }
    my.add_logout_button_to_menu menu
  end
end

config.namespace :manager do |manager|
  manager.authentication_method = :authenticate_user!
  manager.current_user_method = :current_user
  manager.build_menu :utility_navigation do |menu|
    menu.add label: proc{ "#{display_name current_user.name} -My Stuff" },
           url: proc { my_dashboard_path },
           id: 'current_user',
           priority: 1,
           if: proc { current_user.can_be_user? }
    menu.add label: 'Admin Dashboard',
           url: proc { admin_dashboard_path },
           if: proc { current_user.can_be_admin? }
    manager.add_logout_button_to_menu menu
  end
end

根据需要添加其他命名空间的菜单链接,以便可以访问Manager页面(管理员链接适用于站点管理员)...

然后,对于 manager 命名空间中的 Things ,我会覆盖控制器以仅获取所管理的内容。

ActiveAdmin.register Thing, namespace: :manager do

controller do
  def scoped_collection
    Thing.where( user_id: current_user.employers.collect { |e| e.user_id } )
  end
end

所以无论如何这都得到了我想要的影响。