我有一个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
但是,这种方法要求开发人员记住应检查哪些属性,似乎容易遗忘并且不是完全干燥。也许,我这是错误的方式?欢迎所有建议。
答案 0 :(得分:1)
通过预先覆盖input
覆盖Pundit策略的模块来拦截ActiveAdminForm似乎运行良好。以下是我使用的实现:
# /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让我走上了正确的道路。
答案 1 :(得分: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