Traducir Modelos en Laravel 11 Sin Dependencias

Traducir Modelos en Laravel 11 Sin Dependencias

Salva Terol
Salva Terol
Publicado el 07 de septiembre, 2024

Trabajar con modelos multilenguaje en Laravel 11 es esencial cuando desarrollas aplicaciones para usuarios en diferentes países. Aunque existen paquetes que facilitan esta tarea, también es posible lograrlo sin dependencias externas. En este artículo, veremos cómo estructurar nuestras tablas y modelos para gestionar traducciones de forma eficiente.

#Estructura de la Base de Datos

Primero, necesitamos una estructura de base de datos que incluya una tabla para el modelo principal (por ejemplo, posts) y otra para las traducciones (post_translations). De esta forma, almacenamos la información principal en la tabla de posts y los textos traducidos en post_translations.

    
Schema::create('posts', function (Blueprint $table) {
$table->id();
$table->dateTime('publish_date')->nullable();
$table->foreignId('user_id')->constrained();
$table->softDeletes();
$table->timestamps();
});
 
Schema::create('post_translations', function (Blueprint $table) {
$table->id();
$table->foreignId('post_id')->constrained()->cascadeOnDelete();
$table->string('locale');
$table->string('title');
$table->longText('content');
$table->softDeletes();
$table->timestamps();
});

#El Modelo Post

El modelo principal, Post, se encargará de gestionar las traducciones a través de una relación hasMany con el modelo PostTranslation. Además, se utilizará una relación hasOne para cargar automáticamente la traducción correspondiente al idioma actual.

    
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\HasOne;
 
class Post extends Model
{
protected $fillable = ['publish_date', 'user_id'];
 
protected $with = ['currentTranslation'];
 
public function translations(): HasMany
{
return $this->hasMany(PostTranslation::class);
}
 
public function currentTranslation(): HasOne
{
return $this->translations()->one()->where('locale', app()->getLocale());
}
 
public function author(): BelongsTo
{
return $this->belongsTo(User::class, 'user_id');
}
 
public function title(): Attribute
{
return new Attribute(
get: fn() => $this->defaultTranslation->title,
);
}
 
public function content(): Attribute
{
return new Attribute(
get: fn() => $this->defaultTranslation->content,
);
}
}

#El Modelo PostTranslation

El modelo PostTranslation gestionará las traducciones de cada campo de texto en diferentes idiomas. Su relación con el modelo principal Post será a través de una relación belongsTo.

    
use Illuminate\Database\Eloquent\Model;
 
class PostTranslation extends Model
{
protected $fillable = ['post_id', 'locale', 'title', 'content'];
 
public function post()
{
return $this->belongsTo(Post::class);
}
}

#Guardar Publicaciones con Traducciones

Cuando guardamos una nueva publicación, podemos hacerlo incluyendo todas las traducciones en un solo paso. Esto se puede gestionar desde el controlador de la siguiente manera:

    
$post = Post::create([
'publish_date' => now(),
'user_id' => auth()->id(),
]);
 
$post->translations()->createMany([
['locale' => 'en', 'title' => 'English Title', 'content' => 'Content in English'],
['locale' => 'es', 'title' => 'Título en Español', 'content' => 'Contenido en Español'],
]);

#Consideraciones Finales

Aunque existen paquetes para manejar la traducción de modelos en Laravel, implementar este enfoque sin dependencias te da más control sobre el código. Además, esta solución es altamente escalable y fácil de personalizar según las necesidades de tu aplicación.

0 Comentarios

Obtenga ayuda o comparta algo de valor con otros lectores.