2015-04-07 30 views
5

Ho un'app Rails 4 che utilizza Active Admin 1.0.0.pre1 in congiunzione con pundit 0.3.0 per l'autorizzazione che ha funzionato perfettamente fino ad ora, ma ho problemi a trovare un buon modo per personalizzare automaticamente i moduli in base a quelli di un utente ruolo.Come rimuovere automaticamente gli input del modulo Active Admin con gli attributi consentiti da Pundit?

Attribuite questi modelli:

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 

mi piacerebbe per l'ingresso role per essere rimosso automaticamente dal modulo.

Una possibilità sarebbe qualcosa sulla falsariga di:

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 

ma, che approccio richiede allo sviluppatore di ricordare quali attributi devono essere controllati, sembra incline alla dimenticanza e non è esattamente SECCO. Forse, sto andando su questo nel modo sbagliato? Tutti i suggerimenti sono benvenuti

+1

Sono sicuro al 95%, la risposta si nasconde da qualche parte lungo il metodo 'main_content' qui: https://github.com/activeadmin/activeadmin/blob/master/lib/active_admin/views/pages/form.rb. Al momento non ho un progetto aperto con AA per testarlo, ma puoi ignorare quella classe e provare manualmente a escludere l'input ': role' dal buider. –

risposta

1

Intercettare ActiveAdminForm anteponendo un modulo che sostituisce input con un assegno contro la politica Pundit sembra funzionare bene. Ecco l'implementazione con cui sono andato:

# /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 

Grazie a Andrey Deineko per avermi messo sulla strada giusta.

0

Conosco il pundit, non l'attivo_admin. Con questo in mente, usando il codice che hai fornito, ti lancerò un'idea.

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 
+0

Grazie per il suggerimento! Il problema qui è che gli argomenti su 'f.input' variano a seconda del campo, quindi dovrò chiamarli esplicitamente con gli argomenti corretti. Ho aggiornato il mio esempio per riflettere meglio questo. Allo stesso modo, ho preso in considerazione la costruzione di un hash in cui il campo rappresenta la chiave con il valore delle opzioni. Quindi potrei avere un loop di metodo helper sull'hash per effettuare le chiamate corrette, ma speravo in un'integrazione più stretta. –