Usando: attr_accessible com autorização baseada em função
-
16-09-2019 - |
Pergunta
Na minha loja on-line, os usuários têm permissão para alterar certas propriedades de seus pedidos (por exemplo, o seu endereço de cobrança), mas não em outras (por exemplo, a origem endereço IP). Administradores, por outro lado, estão autorizados a modificar todas propriedades ordem.
Dada, este, como posso usar :attr_accessible
para prender adequadamente o meu modelo de Ordem? Ou será que eu tenho que usá-lo para marcar acessíveis todos os atributos que os administradores podem modificar e se abster de utilizar Order.update_attributes(params[:order])
nessas ações do controlador que os usuários comuns podem acessar?
Solução
De um modo geral, attr_accessible não é a ferramenta que você está procurando e Rails não vêm com qualquer coisa construído em que faz o que quiser.
Se você quer o controle de grão fino sobre quem pode atualizar atributos específicos em um modelo, você poderia fazer algo como:
class Order < ActiveRecord::Base
def update_attributes_as_user(values, user)
values.each do |attribute, value|
# Update the attribute if the user is allowed to
@order.send("#{attribute}=", value) if user.can_modify?(attribute)
end
save
end
end
Em seguida, você pode mudar seu Order.update_attributes(params[:order])
para Order.update_attributes_as_user(params[:order], current_user)
e supondo que você implementar o método User#can_modify?
para retornar verdadeiro nos casos corretos, ele deve funcionar.
Outras dicas
Eu tive o mesmo problema e agora eu estou usando esta jóia http://github.com/dmitry/ attr_accessible_block
É fácil e usado em algum site de produção.
Sim, você terá que modificar as ações, de modo que as permissões são verificadas dentro das ações. Chamando Order#update_attributes
não vai funcionar para o usuário em geral.
Eu não posso rember um plugin de autorização baseada em funções que permitiria algo que você está procurando. Isso ocorre porque esses plugins mixin para os controladores e não os modelos. Eles também precisam mixin em ActiveRecord::Base
para verificar se há attr_accesible
etc.