5

我有一个 Rails 4 应用程序,它使用 Active Admin 1.0.0.pre1 和 pundit 0.3.0 进行授权,到目前为止它工作得很好,但是我很难找到一种基于用户角色自动自定义表单的好方法。

鉴于这些模型:

ActiveAdmin.register AdminUser do
  permit_params do
    Pundit.policy(current_admin_user, resource).permitted_attributes
  end

  form do |f|
    f.inputs "Admin Details" do
      f.input :role, as: :select, collection: [:manager, :admin]
      f.input :email, as: :email
      f.input :password
      f.input :password_confirmation
    end
    f.actions
  end
end

class AdminUserPolicy < ApplicationPolicy
  def permitted_attributes
    attributes = [:email, :password, :password_confirmation]
    attributes += [:role] if user.has_role? :super_admin
    attributes
  end
end

我希望role输入自动从表单中删除。

一种选择是:

  permitted_attributes = Pundit.policy(current_admin_user, resource).permitted_attributes

  form do |f|
    f.inputs "Admin Details" do
      f.input :role if permitted_attributes.include? :role
      f.input :email
      f.input :password
      f.input :password_confirmation
    end
    f.actions
  end

但是,这种方法要求开发人员记住应该检查哪些属性,似乎容易健忘并且不完全干燥。也许,我正在以错误的方式解决这个问题?欢迎所有建议。

4

2 回答 2

1

通过预先添加一个覆盖 Pundit 策略的模块来拦截 ActiveAdminForminput似乎效果很好。这是我使用的实现:

# /lib/active_admin/permitted_active_admin_form.rb
module PermittedActiveAdminForm
  def permitted_attributes
    policy = Pundit.policy(current_admin_user, resource)
    policy.respond_to?(:permitted_attributes) ? policy.permitted_attributes : []
  end

  def input(*args)
    super(*args) if permitted_attributes.include? args[0]
  end
end


# /config/initializers/active_admin.rb
module ActiveAdmin
  module Views
    class ActiveAdminForm < FormtasticProxy
      prepend PermittedActiveAdminForm
    end
  end
end

# /app/admin/admin_user.rb
ActiveAdmin.register AdminUser do
  permit_params do
    resource ||= AdminUser
    Pundit.policy(current_admin_user, resource).permitted_attributes
  end

  form do |f|
    f.inputs "Admin Details" do
      f.input :role, as: :select, collection: [:manager, :admin]
      f.input :email, as: :email
      f.input :password
      f.input :password_confirmation
    end
    f.actions
  end
end

感谢 Andrey Deineko 让我走上了正确的道路。

于 2015-04-10T21:30:23.233 回答
0

我知道权威人士,而不是 active_admin。考虑到这一点,使用您提供的代码,我将在那里提出一个想法。

whitelist = Pundit.policy(current_admin_user, resource).permitted_attributes
fields    = %i( role email password password_confirmation )

form do |f|
  f.inputs "Admin Details" do
    (fields & whitelist).each do |field|
      f.input field
    end
  end
  f.actions
end
于 2015-04-09T19:53:18.950 回答