Autoridade é uma ótima estrutura de autorização para aplicativos Rails. É muito simples por padrão, mas também lida bem com cenários mais complicados. Eu sugiro fortemente que você dê uma olhada.
Recursos herdados também economizam muito tempo quando seus controladores contêm principalmente o código clichê que todos nós conhecemos e amamos.
Veja como fazer com que eles trabalhem juntos.
NOTA: Este é um documento de trabalho. Enquanto escrevo meu aplicativo, tenho certeza de que essa integração se tornará mais complexa, mas por enquanto funciona bem. Por favor, deixe-me saber se você pode ver algum espaço para melhorias. Também estou contando com ActiveSupport::Concern
a simplificação do módulo. Eu guardo minhas preocupações em um diretório chamado concerns
em app
. Eu chamei este inherited_resources_with_authority.rb
e você pode precisar modificar seu autoload_paths
in application.rb
para carregar arquivos desta pasta.
module InheritedResourcesWithAuthority
extend ActiveSupport::Concern
included do
inherit_resources
authorize_actions_for :resource_class
alias_method_chain :resource, :authority
alias_method_chain :build_resource, :authority
alias_method_chain :update_resource, :authority
end
protected
def resource_with_authority
resource_without_authority
authorize_action_for(get_resource_ivar)
end
def build_resource_with_authority
build_resource_without_authority
authorize_action_for(get_resource_ivar)
end
def update_resource_with_authority(object, attributes)
object.assign_attributes(*attributes)
authorize_action_for(object)
object.save
end
end
Basicamente, estamos encadeando inherited_resources
métodos abstratos importantes e inserindo nosso código de autorização quando necessário. O último é o mais complicado, pois não podemos chamar o método original ao qual estamos encadeando, então temos que duplicar parte do inherited_resources
código aqui.
Para usar essa preocupação, basta ligar include InheritedResourcesWithAuthority
do seu controlador.
Observe que você não deve usar o método de herança de classe de ativação inherited_resources
em seu controlador, pois já estamos usando o outro método nesta questão.