WinRoadのLaravel4初心者講座

次世代PHPフレームワークのLaravel4を初心者向けに解説して参ります。

Winroad徒然草の管理人がお届けします
hasManyとbelongsTo

hasManyとbelongsTo

このエントリーをはてなブックマークに追加

1対多のリレーション

Userは多くのMessageを発信することができますが、発信されたMessageの所有者(User)は、1人だけです。このような関係を1対多の関係といいます。そして、そのMessaeに対して、Commentが多数寄せられたとしたら、MessageとCommentの関係も1対多の関係となります。1対多の関係は、hasManyを使って紐付けします。

hasMany(モデル名,外部キー、内部キー)

hasManyは、hasOneと同様に第1引数に関連づけをするモデル名を記述します。第2引数に外部キー、第3引数に内部キーを指定するところも同様です。第2引数の外部キーと第3引数の内部キーを省略できるところも同様です。つまり、引数の記述方法は全く同じです。

それでは、何が違うのでしょうか。hasOneとhasManyでは、関連モデルの紐付けが違います。hasOneでは、一つのモデルに対して一つの関連モデルが紐付けされていましたが、hasManyでは、一つのモデルに対して複数のモデルが紐付けされています。 ですので、hasOneとhasManyの一番の違いは、紐付けされているモデルが一つなのか、複数なのかの違いがあります。

それでは、実際に作成してみましょう。まず、Userモデル、Messageモデル、Commentモデルにそれぞれ、リレーションを設定します。

app/models/User.php

class User extends Eloquent{
 public function messages(){
 //Userモデルは多くのMessageを持つことができる
 return $this->hasMany('Message');
 }
  • 4行目:hasManyの第2引数が、user_idで、第3引数が、idの場合は省略することができます。

app/models/Message.php

class Message extends Eloquen{
 public function comments(){
 //Messageモデルは多くのCommentを持つことができる
 return $this->hasMany('Comment');
 }
 public function user(){
 //Messageモデルは、一人のUserに属している
 return $this->belongsTo('User');
 }
  • 4行目:hasManyの第2引数が、message_idで、第3引数が、idの場合は省略することができます。
  • 8行目:belongsToの第2引数が、user_idで、第3引数がidの場合は省略することができます。

app/models/Comment.php

class Comment extends Eloquent{
 public function message(){
 //Commentモデルは、一つのMessageに属している
 return $this->belongsTo('Message');
 }
  • 4行目:belongsToの第2引数が、message_idで第3引数がidの場合は省略することができます。

関連モデルの呼び出し

つぎに、実際にhasManyの関連モデルを呼び出してみましょう。

app/controllers/UserController.php

public function getIndex(){
 $users=User::all();
 return View::make('user/index',compact('users')); 
}
  • UserController.phpは、hasOneの時に使用した例と同じです。全てのUserモデルをビューファイルに引き渡しています。

app/views/user/index.blade.php

<ul>
 @foreach($users as $user)
 <li>{{$user->name}}
 <ul>
 @foreach($user->messages as $message)
 <li>{{$message->title}}</li>
 <ul>
 @foreach($message->comments as $comment)
 <li>{{$comment->body}}</li>
 @endforeach
 </ul>
 @endforeach
 </ul>
 </li>
 @endforeach
 </ul>
  • 2行目:ユーザーの数だけ繰り返します。
  • 5行目:ユーザーが発信したメッセージの数だけ繰り返します。
  • 6行目:メッセージに対するコメントの数だけ繰り返します。

上記例でもわかるように、コントローラーでは、Userモデルしか呼び出していません。しかし、各モデル(Userモデル、Messageモデル、Commentモデル)でリレーションの設定をしていますので、その設定に基づいて各モデル間が紐付けされています。 ですので、Userモデルを元に、Messageモデルのtitleプロパティ(messagesテーブルのtitleフィールド)を呼び出したり、Commentモデルのbodyプロパティを呼び出したり出来ます。

« »

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です