ActiveAdmin,CanCan,Rolify - 无法有条件地禁用过滤器

dim*_*rvp 1 ruby ruby-on-rails-3 activeadmin

到目前为止,这个组合设置中的大部分内容都运行良好.但是,当我尝试有条件地禁用过滤器时,它们只是始终启用.我的场景是(或多或少)我想给Restaurant所有者(AdminUser带有角色:restaurateur)部分访问:他们只能编辑他们自己的餐厅,我也想隐藏他们的一些字段.这有效.但禁用过滤器却没有.让我详细说明:

# app/admin/restaurants.rb
batch_action :activate, :if => proc { can? :activate, Restaurant } do |list|
  #...
end
controller do
  def current_ability
    @current_ability ||= Ability.new(current_admin_user)
  end
end
index do
  ...
  column :city if can? :manage, Restaurant             # This works well.
end
filter :city, :if => proc { can? :manage, Restaurant } # This is always there.
Run Code Online (Sandbox Code Playgroud)

Ability:

# app/models/ability.rb
if user.has_role? :admin
  can :manage, :all
elsif user.has_role? :restaurateur
  cannot :manage, Restaurant
Run Code Online (Sandbox Code Playgroud)

这是我在Rails控制台中看到的内容:

 admin = AdminUser.find(1)                           # roles => [:admin]
 restorateur = AdminUser.find(2)                     # roles => [:restaurateur]
 Ability.new(admin).can?(:manage, Restaurant)        # true
 Ability.new(restorateur).can?(:manage, Restaurant)  # false
Run Code Online (Sandbox Code Playgroud)

我理解我没有以最好的方式使用它,例如使用:manage动词,在通常情况下,动词不是为了提供部分访问.但它可以工作,除了禁用过滤器.

我应该做什么特别的事情,这些确实有用吗?

Rolify在3.2.0.CanCan在1.6.8.ActiveAdmin正在进行GIT修订:b0dd8fdcfbd68984a8c2ec7f2279a121eeb66c3d.如果我将其更新到最新的GIT版本(或官方0.5.0版本),则batch_action总是被禁用!(因此他们也禁用了selectable_column.)

关于我的问题:

有没有可靠的方法来测试ActiveAdmin文件中的能力?也许能力实例化的方式为他们提供错误的用户(我的意思是在检查过滤器:ifProc 之前)?can?在这种情况下,帮助器如何获得实例化,我几乎不知所措.

如果我的方式不正确,有条件地禁用过滤器的推荐方法是什么?

任何人都知道为什么ActiveAdmin的最新版本似乎完全忽略了批量操作?也许我应该把controller do之前batch_action块?

谢谢你的时间.

小智 5

我有同样的问题,并在这个问题上找到了解决方案.

应用此monkeypatch后:

# config/initializers/activeadmin_filter_conditions.rb
module ActiveAdmin
  module Filters
    class FormBuilder < ::ActiveAdmin::FormBuilder
      def filter(method, options = {})
        return "" if method.blank?
        if options[:if].is_a?(Proc)
          return "" if !template.instance_eval(&options[:if])
        end
        options[:as] ||= default_input_type(method)
        return "" unless options[:as]
        content = input(method, options)
        form_buffers.last << content.html_safe if content
      end
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

您应该能够使用您提到的方式在过滤器中使用条件:

filter :city, :if => proc { can? :manage, Restaurant }
Run Code Online (Sandbox Code Playgroud)