Saltar al contenido

¿Cómo puedo implementar la herencia de una sola tabla usando Eloquent de Laravel?

Puede darse el caso de que halles algún problema en tu código o trabajo, recuerda probar siempre en un entorno de testing antes subir el código al proyecto final.

Solución:

Antes de profundizar en mesa múltiple herencia quiero perder unas palabras sobre mesa individual herencia. La herencia de tabla única es la forma más fácil cuando se trata de herencia con modelos de base de datos.
Tiene varios modelos vinculados a la misma tabla y un type columna para distinguir entre las diferentes clases de modelos. Sin embargo, la razón por la que normalmente desea implementar la herencia es porque los modelos tienen propiedades compartidas, pero también algunas que son exclusivas del modelo.
Cuando se usa la herencia de una sola tabla, su tabla se ve similar a esa en algún momento:

id   shared_column   question_column   article_column   question_column2   article_column2 etc...
1    Lorem           62                NULL             test               NULL
2    Ipsum           NULL              x                NULL               true

Terminas teniendo muchos valores NULL porque hay columnas que no son necesarias para cierto tipo de modelo. Y con muchos registros, esto puede influir en el tamaño de la base de datos.

Sin embargo, para algunos casos, podría ser la mejor solución. Aquí hay un tutorial bien escrito que muestra cómo implementarlo en Laravel de una manera bastante elegante.

Herencia de tablas múltiples

Ahora echemos un vistazo a la herencia de varias tablas. Con este método, divide su tabla única en varias (bueno, supongo que el nombre ya lo delató;)) Vamos a usar una técnica llamada polimorfismo

Nuestro esquema del ejemplo anterior se vería así:

posts table:

id   shared_column  postable_id  postable_type
1    Lorem          1            Question
2    Ipsum          1            Article


questions table:

id   question_column   question_column2
1    62                test


articles table:

id   article_column   article_column2
1    x                true

Mucho más limpio si me preguntas…

Las columnas interesantes aquí son postable_id y postable_type. El tipo nos dice en qué tabla encontraremos nuestro “resto” del modelo y el id especifica el primario key del registro que le pertenece. Tenga en cuenta que los nombres de las columnas pueden ser lo que quiera, pero es una convención llamarlo “-poder”.

Echemos un vistazo a los modelos Eloquent ahora.

Correo

class Post extends Eloquent 
    // all your existing code
    
    public function postable()
        return $this->morphTo();
    

Pregunta / Artículo / cualquier otro tipo publicable

class Question extends Post 
    public function post()
        return $this->morphOne('Post', 'postable');
    

Tenga en cuenta que en realidad no tiene que extenderse desde Post pero puede hacerlo si tiene métodos que también desea utilizar. De todos modos, la relación polimórfica funcionará con o sin ella.

Ok, esa es la configuración básica. Así es como puedes usar tus nuevos modelos:

Recuperar todas las publicaciones

$posts = Post::all();

Recuperar todas las preguntas

$questions = Question::all();

Obtener columnas de preguntas de una publicación

$post = Post::find(1);
$question_column2 = $post->postable->question_column2;

Obtener propiedades de publicación de la pregunta

$question = Question::find(1);
$shared_column = $question->post->shared_column;

Comprobar de qué tipo es una publicación

$post = Post::find(1);
echo 'type: '.get_class($post->postable);
if($post->postable instanceof Question)
    // Looks like we got a question here

Crear nueva pregunta

Ahora tengan paciencia conmigo, crear un modelo es un poco más complicado. Si tiene que hacerlo en varios lugares de su aplicación, le sugiero que escriba una función reutilizable para ello.

// create a record in the questions and posts table

$question = new Question();
$question->question_column = 'test';
$question->save();

$post = new Post();
$post->shared_column = 'New Question Post';
$post->save();

// link them together

$question->post()->save($post);

Como puede ver, una base de datos limpia tiene su precio. Será un poco más complejo manejar su modelo. Sin embargo, puede poner toda esta lógica adicional (por ejemplo, que se requiere para crear un modelo) en una función en su clase de modelo y no se preocupe demasiado por eso.

Además, también hay un buen Tutorial para la herencia de tablas múltiples con laravel. Tal vez ayude 😉

de Laravel 5.2, Global Scope está disponible:

class Article extends Post

    protected $table = 'posts';

    protected static function boot()
    
        parent::boot();

        static::addGlobalScope('article', function (Builder $builder) 
            $builder->where('type', 'article');
        );

        static::creating(function ($article) 
            $article->type = 'article' 
        ); 
    

where type = 'article' se agrega a todas las consultas de Article al igual que SoftDeletes.

>>> AppArticle::where('id', 1)->toSql()
=> "select * from `posts` where `id` = ? and `type` = ?"

En realidad, laravel proporciona SoftDeletes rasgo usando esta función.

Aquí tienes las comentarios y puntuaciones

Si crees que te ha sido de utilidad nuestro artículo, te agradeceríamos que lo compartas con el resto juniors de esta manera contrubuyes a difundir este contenido.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *