当前位置: 首页 > 面试题库 >

如何使用Laravel的Eloquent实现单表继承?

轩辕奕
2023-03-14
问题内容

目前,我有一个名为的模型类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...
}

我想将帖子分为两种不同的类型;articlesquestions。我认为做到这一点的最佳方法是通过继承,所以Article并且Question会扩展Post。最佳方法是什么?从哪里开始?


问题答案:

在深入探讨 多表 继承之前,我想谈一谈 单表 继承。当涉及到数据库模型的继承时,单表继承是更简单的方法。
您有多个模型绑定到同一张表,并有一个type列来区分不同的模型类。但是,您通常要实现继承的原因是因为模型具有共享的属性,但也具有模型唯一的属性。
使用单表继承时,您的表在某些时候看起来类似于:

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值,因为某些类型的模型不需要某些列。并且由于记录很多,这可能会影响数据库的大小。

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

多表继承

现在让我们看一下多表继承。通过这种方法,您可以将单个表拆分为多个表(好吧,我猜这个名字已经给您了;)我们将使用一种称为多态的技术

上面示例中的架构如下所示:

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

如果你问我,那会更干净…

这里有趣的列是postable_idpostable_type。该类型告诉我们在哪个表上可以找到模型的“其余部分”,并且id指定属于该记录的主键。请注意,列名称可以是您想要的任何名称,但是习惯上称它为
“ -able”

现在让我们看看Eloquent模型。

发布

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');
    }
}

请注意,实际上您不必从扩展,Post但是如果您也有要使用的方法,则可以。无论如何,无论有没有多态关系都可以使用。

好的,这是基本设置。这是使用新模型的方法:

检索所有帖子

$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
}

提出新问题

现在让我忍受,创建模型要复杂一些。如果必须在应用程序中的多个位置执行此操作,建议您为其编写可重用的函数。

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

因此,您可以看到,干净的数据库附带了价格。处理您的模型会更加复杂。但是,您可以将所有这些额外的逻辑(例如,创建模型所需的所有逻辑)放入模型类的函数中,不必太担心。

另外,还有一个很好的教程,用于使用laravel进行多表继承。也许有帮助;)



 类似资料:
  • 有两个表 表 user id name 1 tom 2 jerry 表 friend id user_id support_id 1 1 1 2 1 2 表 support id name can_fly 1 bird 1 2 dog 0 三个 Model 我想实现如下 sql,意义为 获取 tom 所有会飞的朋友 关系 我这样写,但后边的不会写了,求解。

  • 问题内容: 我有以下口才的查询(这是查询的简化版本,其中包含更多s和s,因此是实现此目的的明显回旋方式-该理论很重要): 如您所见,我最早的约会发生在我的约会上或之后。这导致运行单独的查询来获取该日期,然后将该日期用作主查询中的参数。有没有一种雄辩的方法可以将查询嵌入在一起形成一个子查询,因此只有1个数据库调用而不是2个? 编辑: 根据@Jarek的答案,这是我的查询: 这些块使查询中的所有参数突

  • 问题内容: 我是Laravel的新手。我正在开发laravel 5应用程序,并且卡在这里。我有2个这样的模型: 消息和用户之间存在多对多关系,因此给我一个数据透视表: 我有这样的SQL查询: 如何将此查询转换为laravel对等词? 问题答案: 下面的代码解决了我的问题:

  • 我严重卡在一张有复合钥匙的桌子上。我试图用雄辩的口才通过两个主键过滤记录。但是我开始知道雄辩不支持复合键。我经历了许多解决方案,但没有一个解决方案足够清晰,让初学者理解。 解决方案代码表示使用以下代码编辑模型类: 我想使用laravel提供的资源控制器执行更新功能:我的代码如下所示: 另外,请指导我如何使用带有主键的资源控制器,因为它会为一些参数抛出错误?请帮帮我。我读了很多在线文章,真的很累,但

  • 本文向大家介绍javascript实现继承的简单实例,包括了javascript实现继承的简单实例的使用技巧和注意事项,需要的朋友参考一下 作为一门面向对象的语言,那么继承自然就是一大特征,下面是一段非常简单代码实例,它演示了实现继承的基本原理,有兴趣的或者恰好要学习此方面的朋友可以参阅一下,希望能够给大家来帮组。 以上所述就是本文的全部内容了,希望大家能够喜欢。

  • 问题内容: 我正在使用Laravel Eloquent查询构建器,并且在一个查询中需要多个条件的子句。它可以工作,但并不优雅。 例: 有没有更好的方法可以执行此操作,还是应该坚持使用此方法? 问题答案: 在Laravel 5.3中从6.x开始仍然适用,您可以使用更细粒度的wheres作为数组传递: 就个人而言,我并没有在多个调用中找到用例,但事实是您可以使用它。 自2014年6月起,您可以将数组传