Laravel: Convención sobre Configuración
Estar en la misma página aquí son convenciones de nomenclatura que conoces y usaste miles de millones de veces:
StudlyCase/PascalCase
Ejemplo: StudlyCase
el caso de Carmel
Ejemplo: camelCase
serpiente_caso
Ejemplo: snake_case
caja de kebab
Ejemplo: kebab-case
¿Por qué necesitamos convenciones?
Imagina que tienes modelos de User
y Post
. Desea obtener todas las publicaciones de un usuario. Y tenemos una relación de uno a muchos entre los modelos de User
y Post
.
Sin convenciones
// Posts table migration
// ...
$table->foreignId('author_id')->constrained();
// ...
Ahora, cuando vamos a definir una relación entre los modelos User
y Post
, tenemos que escribir algo como esto:
// User model
// ...
public function posts()
{
return $this->hasMany(Post::class, 'author_id');
}
// ...
¿Ve la diferencia? Tenemos que ser explícitos sobre el nombre de la clave externa.
Con convenciones
// Posts table migration
// ...
$table->foreignId('user_id')->constrained();
// ...
Ahora, cuando definimos una relación entre los modelos User
y Post
, toma la forma de algo como esto:
// User model
// ...
public function posts()
{
return $this->hasMany(Post::class);
}
// ...
y usando las convenciones bien definidas, podemos omitir el trabajo extra que el framework ya está haciendo por nosotros.
Ahora la parte aburrida ha terminado. Vayamos al grano.
Convenciones de nombres
Modelos
Usa la forma singular de la palabra. Ejemplo: : User
, Post
, Comment
, Tag
. Para modelos de varias palabras, use PascalCase. Ejemplo: UserPost
, UserComment
, UserTag
.
Mesas
Usa la forma plural de la palabra. Ejemplo: : users
, posts
, comments
, tags
. Para nombres de tablas de varias palabras, use snake_case
.
Controladores
Utiliza la forma plural de la palabra. Ejemplo:: UsersController
, PostsController
, CommentsController
, TagsController
; sufijo de Controller
adjunto.
Rutas
Usa la forma plural de la palabra. Ejemplo: users
, posts
, comments
, tags
. Para rutas de varias palabras, use kebab-case
.
// get all users
Route::get('users', [UsersController::class, 'index'])
->name('users.index');
// show form to create a new user
Route::get('users/create', [UsersController::class, 'create'])
->name('users.create');
// create a new user in the database
Route::post('users', [UsersController::class, 'store'])
->name('users.store');
// show a specific user
Route::get('users/{user}', [UsersController::class, 'show'])
->name('users.show');
// show edit form for a user populated with user data
Route::get('users/{user}/edit', [UsersController::class, 'edit'])
->name('users.edit');
// update a user in the database
Route::put('users/{user}', [UsersController::class, 'update'])
->name('users.update');
// delete a user from the database
Route::delete('users/{user}', [UsersController::class, 'destroy'])
->name('users.destroy');
Las rutas de publicación para un usuario específico se verán así:
// get all posts for a user
Route::get('users/{user}/posts', [PostsController::class, 'index'])
->name('users.posts.index');
// show form to create a new post for a user
Route::get('users/{user}/posts/create', [PostsController::class, 'create'])
->name('users.posts.create');
// create a new post for a user in the database
Route::post('users/{user}/posts', [PostsController::class, 'store'])
->name('users.posts.store');
// show a specific post for a user
Route::get('users/{user}/posts/{post}', [PostsController::class, 'show'])
->name('users.posts.show');
// show edit form for a post for a user populated with post data
Route::get('users/{user}/posts/{post}/edit', [PostsController::class, 'edit'])
->name('users.posts.edit');
// update a post for a user in the database
Route::put('users/{user}/posts/{post}', [PostsController::class, 'update'])
->name('users.posts.update');
// delete a post for a user from the database
Route::delete('users/{user}/posts/{post}', [PostsController::class, 'destroy'])
->name('users.posts.destroy');
Si configuramos rutas de esta manera y tenemos una relación de posts
definida en el modelo de User
como esta:
// User model
// ...
public function posts()
{
return $this->hasMany(Post::class);
}
// ...
Luego, podemos usar la relación de posts
y el enlace del modelo de ruta para que el método PostsController
funcione así:
// PostsController
// ...
// create a new post for a user in the database
public function store(User $user)
{
$user->posts()->create($this->validatePost());
return redirect()->route('users.posts.index', $user);
}
// ...
Las convenciones de Laravel hacen que el código sea más expresivo y declarativo, al mismo tiempo que nos evita escribir código adicional.
Rutas con nombre
Use la forma plural de la palabra y agregue el nombre de la acción; p.ej; users.index
usando notación de puntos en b/n.
// users.index named route
Route::get('users', [UsersController::class, 'index'])
->name('users.index');
Para modelo/acción de varias palabras, use kebab-case
; p.ej; new-car.refuel-and-ignite
.
// new-car.refuel-and-ignite named route
Route::post('new-car/refuel-and-ignite', [NewCarController::class, 'refuelAndIgnite'])
->name('new-car.refuel-and-ignite');
Puntos de vista
Estructura de directorios
Usa la forma plural de la palabra y todo en minúsculas. Ejemplo: users
, posts
, comments
, tags
. Para modelo/acción de varias palabras, use kebab-case
;
Nombre de archivo
Use index.blade.php
para listar todos los registros, create.blade.php
para crear un nuevo registro, show.blade.php
para mostrar un registro específico, edit.blade.php
para editar un registro específico.
// UsersController
// ...
// show all users
public function index()
{
$users = User::all();
// this is expressive and declarative and more aligned with the
// naming conventions we've been following
return view('users.index', ['users' => $users]);
}
// ...
Relaciones
Use la relación w.r.t de forma singular/plural y use snake_case para nombres de modelos de varias palabras.
// single-word has many relationship
public function posts()
{
return $this->hasMany(Post::class);
}
// multi-word has many relationship
public function user_posts()
{
return $this->hasMany(UserPost::class);
}
// loading single-word has many relationship
$users = User::with('posts')->get();
// loading multi-word has many relationship
$users = User::with('user_posts')->get();
Cuando definimos las relaciones con estas convenciones de nomenclatura; son fascinantes y están más alineados con la notación de punto (.).
Si tenemos una relación de tags
definida en la Post
; podemos cargarlo así:
// load all users with their posts and tags
$users = User::with('posts.tags')->get();
Misceláneas
Para las interfaces, puede usar el directorio app/Contracts
.
Para implementar la interfaz, puede usar el directorio app/Actions
.
En los rasgos, puede usar el directorio app/Concerns
.
En otros, los comandos artisan
están ahí para ayudarlo a poner las cosas en su lugar correcto.
Conclusión
Espero que encuentre útil este artículo. Si tiene alguna pregunta o sugerencia, no dude en comentar a continuación.
Gracias por llegar hasta aquí, si encuentras esto útil no olvides dejar un👍🏼y suscribirse para recibir más contenido.
Si le interesa, puede echar un vistazo a algunos de los otros artículos que he escrito recientemente sobre AWS y Laravel: