Integrar recursos herdados com autoridade

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::Concerna simplificação do módulo. Eu guardo minhas preocupações em um diretório chamado concernsem app. Eu chamei este inherited_resources_with_authority.rbe você pode precisar modificar seu autoload_pathsin application.rbpara 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_resourcesmé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_resourcescódigo aqui.

Para usar essa preocupação, basta ligar include InheritedResourcesWithAuthoritydo seu controlador.

Observe que você não deve usar o método de herança de classe de ativação inherited_resourcesem seu controlador, pois já estamos usando o outro método nesta questão.