2015-04-07 6 views
5

Ich habe eine Rails 4 App mit Active Admin 1.0.0.pre1 in Verbindung mit Pandit 0.3.0 für die Autorisierung, die bisher einwandfrei funktioniert hat, aber ich habe Probleme, herauszufinden, eine gute Möglichkeit, Formulare automatisch auf Basis eines Benutzers anpassen Rolle.Wie automatisch Active-Admin-Formular-Eingaben mit Pundit zulässigen Attribute entfernen?

Da diese Modelle:

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 

ich für den role Eingang möchte automatisch aus der Form entfernt werden.

Eine Möglichkeit etwas entlang der Linien von wäre:

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 

aber, dass Ansatz erfordert den Entwickler daran zu erinnern, welche Attribute überprüft werden soll, scheint anfällig für Vergesslichkeit und ist nicht gerade trocken. Vielleicht gehe ich das falsch herum? Alle Vorschläge sind willkommen.

+1

Ich bin zu 95% sicher, die Antwort versteckt sich irgendwo auf dem 'main_content' Methode hier: https://github.com/activeadmin/activeadmin/blob/master/lib/active_admin/views/pages/form.rb. Ich habe momentan kein offenes Projekt mit AA, um es zu testen, aber Sie können diese Klasse überschreiben und versuchen, die '' role''-Eingabe von Buider manuell auszuschließen. –

Antwort

1

Intercepting ActiveAdminForm durch ein Modul, das Voranstellen input mit einem Scheck gegen die Pundit Richtlinie überschreibt scheint gut zu funktionieren. Hier ist die Implementierung, die ich mit ging:

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

Dank Andrey Deineko für mich auf den richtigen Weg.

0

Ich kenne Pandit, nicht active_admin. In Anbetracht dessen, mit dem Code, den Sie zur Verfügung gestellt haben, werde ich einfach eine Idee da draußen werfen.

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

Danke für den Vorschlag! Das Problem hier ist, dass die Argumente für "f.input" abhängig von dem Feld variieren, so dass ich jeden explizit mit den richtigen Argumenten aufrufen muss. Ich habe mein Beispiel aktualisiert, um das besser widerzuspiegeln. Aus demselben Grund dachte ich darüber nach, einen Hash zu erstellen, bei dem das Feld den Schlüssel darstellt, wobei der Wert die Optionen ist. Dann könnte ich eine Hilfsmethode über den Hash laufen lassen, um die richtigen Aufrufe zu machen, aber ich hatte auf eine engere Integration gehofft. –