在我深入研究之前多桌继承我想多说几句单桌遗产。当涉及到数据库模型的继承时,单表继承是更简单的方法。
您有多个模型绑定到同一个表和一个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 值,因为某些类型的模型不需要某些列。对于大量记录,这会影响数据库的大小。
但对于某些情况,它可能仍然是最佳解决方案。这里有一个写得很好的Tutorial http://codebyjeff.com/blog/2014/07/single-table-inheritence-in-laravel这展示了如何在 Laravel 中以非常优雅的方式实现它。
多表继承
现在让我们看看多表继承。通过这种方法,您可以将单个表分成多个表(好吧,我猜这个名字已经暴露了这种情况;))我们将使用一种称为多态性 http://laravel.com/docs/4.2/eloquent#polymorphic-relations
上面示例中的架构如下所示:
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_id
and postable_type
。类型告诉我们将在哪个表上找到模型的“其余部分”,而 id 指定属于它的记录的主键。请注意,列名称可以是您想要的任何名称,但惯例是这样称呼它"-able".
现在让我们看一下 Eloquent 模型。
Post
class Post extends Eloquent {
// all your existing code
public function postable(){
return $this->morphTo();
}
}
Question / Article / 所有其他可邮寄类型
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);
正如您所看到的,干净的数据库是有代价的。处理你的模型会有点复杂。但是,您可以将所有这些额外的逻辑(例如创建模型所需的逻辑)放入模型类中的函数中,并且不必太担心。
另外,还有一个不错的Tutorial https://web.archive.org/web/20150217020611/http://www.richardbagshaw.co.uk/laravel-user-types-and-polymorphic-relationships/Laravel 也适用于多表继承。也许有帮助;)