プログラム関係の備忘録。技術系記事1000記事以上を目指すブログ

【Laravel5.6】Eloquent利用時にまず知っておきたいこと

  • 2018年5月29日
  • 2018年5月29日
  • PHP
  • 467view
  • 0件
PHP

使い始めのときに便利すぎて逆に混乱することが多かった為、ある程度触った今改めてまとめ。
過去の記事内容との重複箇所あり。
【Laravel】Eloquentを使ったデータベースの操作の基礎

とりあえずこういうものと覚える箇所

公式をちゃんと読んでおくとORMのEloquentの旨みが増える。

モデル名とテーブル名の関係

Eloquentでは明示的に指定しない限り、クラス名を複数形の「スネークケース」にしたものが、テーブル名として使用される。例えばShopというモデルを作るときは、勝手にshopsというテーブルを指定してくれる。
これに従った命名規則でテーブル設計を行っておくとわざわざEloquentでテーブルを指定する必要がなくなる。

明示的に指定する場合は以下のようにする
[php] // 関連付けるテーブルを明示的に指定
protected $table = ‘(テーブル名)’;
[/php]

主キーの関係

主キーに関しても規約があり、idというカラムが主キーであると勝手に認識してくれる。
idが主キーではない場合には、オーバーライドする必要がある。
[php] // 主キーを明示的に指定
protected $primaryKey = ‘(主キーのカラム名)’;
[/php]

リレーションの定義

テーブル同士をJOINするときの記述方法。
SQL書くのに慣れていると逆に混乱するかも。

以下2つのテーブルがある場合

ユーザーテーブル(主テーブル)
id
name
attribute

属性テーブル(従テーブル)
user_id
type

ユーザーモデルが属性モデル一つと関係している場合は、ユーザーモデルで属性メソッド(attribute)を設置し、hasOneメソッドを返す。

例1
[php] <?php
namespace App;
use Illuminate\Database\Eloquent\Model;

class User extends Model
{
public function attribute()
{
return $this->hasOne(‘App\Attribute’);
}
}
[/php]

逆に属性モデルからユーザーモデルを取得する場合は、属性モデルでユーザーメソッドを設置し、belongsToメソッドを返す。

例2
[php] <?php
namespace App;
use Illuminate\Database\Eloquent\Model;

class Attribute extends Model
{
public function user()
{
return $this->belongsTo(‘App\User’);
}
}
[/php]

関連付け自体は上記のように単純だが、肝心のJOINするカラムを指定していない、のに上記でもうまくいくことになる。

その理由は、
例1ではEloquentでUserモデルはAttributeモデルがuser_id外部キーを持っていると仮定し、
例2ではEloquentでAttributeモデルはuser_idに一致するidを持つUserモデルを見つけようとするから。

要は勝手に関連する○○_idを見に行ったりしてくれる。
なのでこれについても命名規則に従うことでJOINするカラムの指定も省くことができる。

これが不本意な場合は第2引数、第3引数にカラムを指定することでオーバーライドすることもできる
[php] public function user()
{
return $this->belongsTo(‘App\User’, ‘foreign_key’, ‘other_key’);
}
[/php]

Eagerローディング

前項のようにテーブルが関連付けられている場合、いつものようにコントローラーで以下のようにデータを取得すると、まずは全ての本を取得し、そのあとその著者を取得するという処理になる為パフォーマンスがよくない。
[php] $books = App\Book::all();

foreach ($books as $book) {
echo $book->author->name;
}
[/php]

そのときはwithメソッドを指定することで解消することができる
[php] $books = App\Book::with(‘author’)->get();

foreach ($books as $book) {
echo $book->author->name;
}
[/php]

複数のリレーションに対するwithメソッドの指定方法は、引数を追加で渡すだけ。
[php] $books = App\Book::with([‘author’, ‘publisher’])->get();
[/php]