現在、という名前のモデルクラスがあり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...
}
投稿を2つの異なるタイプに分けたいと思います。articles
およびquestions
。これを行う最善の方法は継承によるものだと思ったのでArticle
、Question
拡張しPost
ます。これを行うための最良の方法とどこから始めればよいですか?
マルチテーブル継承について掘り下げる前に、シングルテーブル継承について少し説明しておきたいと思います。単一テーブル継承は、dbモデルでの継承に関してはより簡単な方法です。異なるモデルクラスを区別するため
に、同じテーブルと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に非常にエレガントな方法で実装する方法を示すよく書かれたチュートリアルです。
次に、マルチテーブル継承を見てみましょう。この方法では、1つのテーブルを複数のテーブルに分割します(名前はすでにそのようなものを与えていると思います;))ポリモーフィズムと呼ばれる手法を使用します
上記の例のスキーマは次のようになります。
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
とpostable_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を使用したマルチテーブル継承の優れたチュートリアルもあります。多分それは役立ちます;)
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加