如何使用Laravel的雄辩来实现单表继承? [英] How can I implement single table inheritance using Laravel's Eloquent?

查看:171
本文介绍了如何使用Laravel的雄辩来实现单表继承?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

目前我有一个模型类,名为 Post

Currently I have a model class named Post.

class Post extends Eloquent {

    protected $table = 'posts';
    protected $fillable = array('user_id', 'title', 'description', 'views');

    /*
     * Relationships
     */

    public function user()
    {
        return $this->belongsTo('User');
    }

    public function tags()
    {
        return $this->belongsToMany('Tag', 'post_tags');
    }

    public function reactions()
    {
        return $this->hasMany('Reaction');
    }

    public function votes()
    {
        return $this->hasMany('PostVote');
    }

    //Scopes and functions...
}

我想将帖子分为两种类型: 文章问题。我认为最好的方法是继承,所以文章问题将扩展。那么做最好的方法是什么?从哪里开始?

I would like to divide posts into two different types; articles and questions. I thought the best way to do this is by inheritance, so Article and Question would extend Post. What is the best way to do this and where to start?

推荐答案

>继承我想丢失关于单表继承的话。单表继承是使用db模型继承的更简单的方法。

您有多个模型绑定到同一个表和一个类型列区分不同的模型类。但是,您通常希望实现继承的原因是因为模型具有共享属性,而且还具有一些模型唯一的特性。

当使用单表继承时,表格与某些特性类似: p>

Before I dig into multi table inheritance I want to lose a few words about single table inheritance. Single table inheritance is the more easy way when it comes to inheritance with db models.
You have multiple models bound to the same table and a type column to distinguish between the different model classes. However the reason you normally want to implement inheritance is because the models have shared properties but also some that are unique to the model.
When using single table inheritance your table looks similar to that at some point:

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

最终有很多NULL值,因为某些类型不需要列的模型。并且有很多记录可以影响数据库的大小。

You end up having a lot of NULL values because there are columns not needed for a certain type of model. And with a lot of records this can influence the size of database.

然而,在某些情况下,它可能仍然是最好的解决方案。这是一个写得很好的教程,展示了如何在Laravel中实现它优雅的方式。

However for some cases it might still be the best solution. Here's a well written Tutorial that shows how to implement it in Laravel in a pretty elegant way.

现在看看多表继承。使用这种方法,您将单个表拆分成多个表(我猜这个名称已经有了这种名称))我们将使用一种名为多态性

Now lets look at multi table inheritance. With this method you split your single table into multiple ones (well I guess the name gave that kind of away already ;)) We are going to use a technique called Polymorphism

我们从上面的示例中的模式如下所示:

Our schema from the example above would look like this:

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

如果你问我...清洁很多...

A lot cleaner if you ask me...

这里有趣的列是 postable_id postable_type 。该类型告诉我们,我们将在哪个表中找到我们的rest模型,而id指定属于它的记录的主键。请注意,列名称可以是任何您想要的,但它是惯例,称之为可以

The interesting columns here are postable_id and postable_type. The type tells us on which table we will find our "rest" of the model and the id specifies the primary key of the record that belongs to it. Note that the column names could be whatever you want, but it is convention to call it "-able".

让我们来看看

发布

class Post extends Eloquent {
    // all your existing code

    public function postable(){
        return $this->morphTo();
    }
}

问题 / 文章 / 其他可发布类型

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

请注意,您实际上不必从发布,但是如果您可能还有要使用的方法,您可以。无论如何,多态关系可以使用或不使用它。

Note that you actually don't have to extend from Post but you can if you maybe have methods that you want to use too. Anyways, the polymorphic relationship will work with or without it.

确定这是基本设置。以下是您可以使用新模型的方法:

Ok that's the basic setup. Here's how you can use your new models:

检索所有帖子

$posts = Post::all();

检索所有问题

$questions = Question::all();

从帖子中获取问题列

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

从问题中获取帖子属性

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

检查帖子的类型

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

创建新问题

现在承担我,创建一个模型有点多复杂。如果你必须在你的应用程序的多个地方做,我建议你写一个可重用的功能。

Now bear with me, creating a model is a bit more complicated. If you have to do it at multiple places in your application I suggest you write a reusable function for it.

// 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);

所以你可以看到,一个干净的数据库带有价格。处理你的模型会更复杂一些。然而,您可以将所有这些额外的逻辑(例如,创建模型所需的)逻辑放入模型类中的一个函数中,而不必担心它太多。

So as you can see, a clean database comes with it's price. It will be a bit more complex to handle your model. However you can put all these extra logic (e.g. that's required to create a model) into a function in your model class and don't worry about it too much.

另外,有一个很好的教程多表继承与laravel也。也许它有帮助;)

Also, there's a nice Tutorial for multi table inheritance with laravel too. Maybe it helps ;)

这篇关于如何使用Laravel的雄辩来实现单表继承?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆