Atributo UsePolicy de Laravel: control de política explícita
- Publicado el 01 diciembre, 2025
- Palabras: 202
¿Alguna vez has necesitado usar una política diferente a la que sugiere la convención de nomenclatura de Laravel o has querido que las asignaciones de políticas sean perfectamente claras en tu código? El atributo UsePolicy resuelve ambos problemas con elegancia.
Convención vs. Declaración Explícita
El autodescubrimiento de políticas de Laravel sigue una convención de nomenclatura sencilla: un modelo Post se asigna automáticamente a una clase PostPolicy. Esto funciona perfectamente la mayor parte del tiempo, pero hay situaciones en las que se necesita más control:
// Traditional auto-discovery (implicit)
class Post extends Model
{
//
}
// With explicit policy declaration
#[UsePolicy(PostPolicy::class)]
class Post extends Model
{
//
}
El atributo UsePolicy hace explícita la relación de políticas en la definición del modelo, eliminando cualquier duda sobre qué política maneja la autorización.
Ejemplo práctico
Considere un sistema de gestión de contenido donde cada tipo de publicación requiere reglas de autorización diferentes. Podría tener un modelo de publicación general, pero necesitar políticas especializadas para cada tipo de contenido:
<?php
namespace AppModels;
use AppPoliciesAdminContentPolicy;
use IlluminateDatabaseEloquentModel;
use LaravelFrameworkAuthAccessUsePolicy;
#[UsePolicy(AdminContentPolicy::class)]
class Post extends Model
{
protected $fillable = [
'title', 'content', 'status', 'content_type'
];
public function isAdminContent(): bool
{
return in_array($this->content_type, [
'announcement', 'policy_update', 'system_notice'
]);
}
}
class AdminContentPolicy
{
public function view(User $user, Post $post): bool
{
if ($post->isAdminContent()) {
return $user->hasRole('admin') || $user->hasRole('moderator');
}
return $post->status === 'published';
}
public function update(User $user, Post $post): bool
{
if ($post->isAdminContent()) {
return $user->hasRole('admin');
}
return $user->id === $post->user_id || $user->hasRole('editor');
}
public function delete(User $user, Post $post): bool
{
return $user->hasRole('admin') ||
($user->id === $post->user_id && !$post->isAdminContent());
}
}
class PostController extends Controller
{
public function update(Request $request, Post $post)
{
$this->authorize('update', $post); // Uses AdminContentPolicy
$post->update($request->validated());
return redirect()->route('posts.show', $post);
}
}
Este enfoque es especialmente útil cuando se tienen modelos que comparten nombres en diferentes contextos (como los modelos de publicación en módulos de blog y foro), cuando se utilizan políticas compartidas en varios modelos o cuando se desea que las relaciones de autorización sean inmediatamente evidentes para los nuevos miembros del equipo.
El atributo también facilita la compatibilidad con IDE y herramientas de análisis estático, lo que facilita el seguimiento de los flujos de autorización y la comprensión rápida de las implementaciones de seguridad. Se acabó la búsqueda intensiva de convenciones de nomenclatura de archivos para comprender qué política se aplica a cada modelo.
Desarrollador backend especializado en PHP y Laravel, con sede en Santander, Cantabria. Más de 15 años de experiencia en el desarrollo de aplicaciones web a medida y en la modernización de código heredado.
Fuente: Harris Raftopoulos
Inicia la conversación
Hazte miembro de Antonio Jenaro para comenzar a comentar.
Regístrate ahora¿Ya estás registrado? Inicia sesión