2015-04-07 31 views
5

Mam aplikację Rails 4 przy użyciu Active Admin 1.0.0.pre1 w połączeniu z pundit 0.3.0 dla autoryzacji, która działa bez zarzutu do tej pory, ale mam problem z wymyśleniem sposobu automatycznego dostosowywania formularzy w oparciu o użytkownika rola.Jak automatycznie usuwać aktywne formularze formularzy Admin z dozwolonymi atrybutami Pundit?

Biorąc pod uwagę te modele:

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 

Chciałbym dla wejścia role zostać automatycznie usunięte z formularza.

Jedną z opcji byłoby coś wzdłuż linii:

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 

jednak, że podejście wymaga wywoływacza do zapamiętania, które atrybuty powinny być sprawdzane, wydaje się skłonność do zapominania i nie jest dokładnie wysuszyć. Być może, idę o tym w niewłaściwy sposób? Wszystkie sugestie mile widziane.

+1

Mam 95% pewności, odpowiedź kryje się gdzieś wzdłuż metody "main_content" tutaj: https://github.com/activeadmin/activeadmin/blob/master/lib/active_admin/views/pages/form.rb. Nie mam teraz otwartego projektu z AA, aby go przetestować, ale możesz zastąpić tę klasę i spróbuj ręcznie wykluczyć wejście ': role' z buidera. –

Odpowiedz

1

Przechwytywanie ActiveAdminForm przez poprzedzenie moduł, który zastępuje input z czekiem przeciwko polityce Pundit wydaje się działać dobrze. Oto implementacja, z którą poszedłem:

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

Dziękuję Andrey Deineko za rozpoczęcie mnie właściwą drogą.

0

Znam Pundit, nie active_admin. Mając to na uwadze, używając podanego kodu, po prostu wyrzucę pomysł.

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

Dzięki za sugestię! Problem polega na tym, że argumenty dotyczące 'f.input' różnią się w zależności od pola, więc będę musiał wywołać każdy z nich jawnie za pomocą poprawnych argumentów. Zaktualizowałem mój przykład, aby lepiej to odzwierciedlić. Na tej samej próżności rozważałem skonstruowanie skrótu, w którym pole reprezentuje klucz z wartością będącą opcjami. Wtedy mogłem mieć pętlę metody helpera na mieszanie, aby wykonać prawidłowe połączenia, ale miałem nadzieję na ściślejszą integrację. –