Eloquentの使い方 まとめ

2019/08/06

Laravel でのDB操作は 主に Eloquent (エロクアント)を使います。

Eloquent についての詳しい内容は以下を参照ください。

Eloquent の記述はいくつかあり、今回はそれをまとめてみます。

 
INDEX

 

Eloquentメソッド

find()

例)id=1 のレコードを抽出(主キーで指定したモデル取得)


$user = \App\User::find(1);

 

findOrFail()

例)クエリー条件にマッチしたレコードがなかったときに例外処理をする


$user = \App\User::findOrFail(1);
$user = \App\User::where('active', '1')->firstOrFail();

 

where()

例)アクティブのユーザだけ抽出(クエリー条件にマッチしたレコード取得)


$users = \App\User::where('active', '=', 1)->get();

// '=' は省略してもいいです。
$users = \App\User::where('active', 1)->get();

// 最初のレコードだけ取得する場合
$user = \App\User::where('active', 1)->first();

ポイント

get()メソッドが返すのは配列ではありません。dd() メソッドで表示される通り Collection インスタンスです。

コレクション5.1 利用可能なメソッド

 

count()

集計関数も用意されています。


$count = \App\User::where('active', 1)->count();
$max = \App\User::where('active', 1)->max('price');

 

toArray()

コレクション を配列に変換するためには、toArrayメソッドを使って行うことができます。

コレクションとは

Eloquent が複数のレコードをリターンする場合、Illuminate\Database\Eloquent\Collection オブジェクトが返されます。このことから複数のレコードをEloqunetで抽出することをコレクションと呼んだりします。


$user = \App\User::all()->toArray();
dd($user);

出力結果


array:8 [▼
0 => array:5 [▼
"id" => 1
"name" => "デモ"
"email" => "demo@gmail.com"
"created_at" => "-0001-11-30 00:00:00"
"updated_at" => "-0001-11-30 00:00:00"
]
1 => array:5 [▶]
2 => array:5 [▶]
3 => array:5 [▶]
4 => array:5 [▶]
5 => array:5 [▶]
6 => array:5 [▶]
7 => array:5 [▶]
]

 

クエリースコープを使う

例)「人気のあるユーザ」&「アクティブなユーザ」


$users = \App\User::popular()->active()->get();

スコープの定義はモデルに記述します。


:
class User extends Model
{

// 人気のあるユーザ
public function scopePopular($query)
{
return $query->where('votes', '>', 100);
}

// アクティブなユーザ
public function scopeActive($query)
{
$query->where('active', true);
}

}

POINT!

スコープを定義する際、名前の付け方に注意!

動的スコープ(引数を受け取るスコープ)を定義したい場合は以下になります。


// データ検索
$User = new \App\User();
$User->email = $email;
$User->password = $password;

// スコープの使用例(クエリー条件)
$findData = $User->findUserEmailPassword()->first();

スコープの定義は以下のようになります。


:
class User extends Model
{

// eメール と パスワードをクエリー条件に指定
public function scopeFindUserEmailPassword()
{
return $this->where('email', $this->email)->where('password', $this->password);
}

}

 

DBにデータを保存する

DBにデータを保存する方法は、大きく分けて2通りあります。

  • Eloquentでモデルインスタンスを作成して保存
  • SQLで直で保存

Eloquentでモデルインスタンスを作成して保存

createメソッド

「インスタンスの作成+属性の代入+データの保存」を一気にやってくれます。

モデルで fillable か guarded 属性のどちらかを指定する必要があります。(複数代入保護のため)


// model
// fillable か guarded のどちらかを指定する必要あり
protected $fillable = ['name','email'];

// controller
public function store(Request $request)
{
  $user = App\User::create(['name' => '山田太郎','email' => 'yamada@test.com']);
}

 

fillメソッド & saveメソッド

インスタンスの作成 → new
属性の代入 → fillメソッド
DBの保存 → save メソッド

いくつかの処理に分けて行うスタイルです。


// model
// fillable か guarded のどちらかを指定する必要あり
protected $fillable = ['name','email'];

// controller
public function store(Request $request)
{
  $user = new App\User();
  $user->fill(['name' => '山田太郎','email' => 'yamada@test.com']);
  $user->save();
}

 

属性を直埋め & saveメソッド

インスタンスの作成 → new
属性を直埋め
DBの保存 → save メソッド

いくつかの処理に分けて行うスタイルです。

ただし複数代入からは保護されません。


public function store(Request $request)
{
// Userモデルのスンスタンスを生成
$user = new \App\User;

// 属性を直埋め
$user->name = $request->name;
$user->email = $request->email;

// 保存
$user->save();
}

 

SQLで直で保存

複数代入から保護されていないのでセキュリティ的には危険です。

ただし、配列の配列をinsertの引数に渡して一度に多くのレコードをまとめて挿入できるメリットもあります。


App\User::insert(['name'=>'山田太郎','email'=>'yamada@test.com']);

 

レコードの更新処理(UPDATE)

コントローラーにて以下を記述。


public function edit(Request $request)
{
//レコードを検索
$user = \App\User::findOrFail($id);

//値を代入
$user->name = $request->name;

//保存(更新)
$user->save();
}

更新処理は基本的に作成処理と同じです。

違いはUserモデルのインスタンスを生成していないだけ。

save メソッドはデータベースで既に存在するレコードを更新するためにも使用されます。

レコードを更新するにはまず取得する必要があり、更新したい属性をセットしてから saveメソッドを呼び出します。

この場合も updated_at タイムスタンプは自動的に更新されます。

ポイント

以下のような書き方も可能です。
複数いっぺんに更新する場合はカラム名と値を配列にします。


\App\User::where('id',$id)->update(['name' => 'DEMO', 'status'=>1]);

 

削除(DELETE)

コントローラにて以下を記述


public function delete($id){

// 削除対象レコードを検索
$user = \App\User::findOrFail($id);

// 削除
$user->delete();
}

削除するには、deleteメソッドを呼び出します。

findOrFailメソッドで該当レコードを取得してdeleteメソッドを実行。

 

リレーション

モデルを使ってテーブル間同士を結合することができます。

例)お気に入り機能

一人のユーザに対して複数のお気に入りを登録することができる

⇒ Userモデル:Bookmarkモデル = 1:N の関係

⇒ User hasMany Bookmarks / Bookmarks belongsTo User

Userモデル(:N)


class User extends Model 
{ 
public function bookmarks()
{ 
return $this->hasMany('App\Bookmark'); 
}
}

Bookmarkモデル(1:N


class Bookmark extends Model 
{ 
public function user()
{ 
return $this->hasMany('App\User'); 
}
}

それでは実際にEloguentを使って表示してみます。

例)誰がどんなページをブックマークしているか?


//id=1のユーザーを取得
$user = App\User::find(1);

//ブックマークを取得
$bookmarks = $user->bookmarks;

//ユーザー表示
echo "ユーザー名: ".$user->user_name."のブックマーク<BR>";

//ブックマーク表示
foreach($bookmarks as $bookmark)
{
echo $bookmark->page_title."<BR>";
}

//ブックマーク数を表示
echo $bookmarks->count()."数<BR>";

User しか取得していないのに、その下にぶら下がるブックマークを user->bookmarks で取得できるようになります。

今度は逆にブックマークごとにユーザー名を表示してみます。


//ブックマーク一覧取得
$bookmarks = \App\bookmarks::all();

  //ループして表示
  foreach($bookmarks as $bookmark)
  {
      //ユーザー名取得
      echo $bookamrk->user->user_name." ".$bookmark->page_title."<BR>";
  }

ブックマークを取得して、 $bookmark->user->user_name でユーザー名を得ることができます。

POINT!

DBファサードを使ってJoin句でインナージョインすることも可能です。この場合、モデルをいじる必要はありません。

Eloquentの使い方については以上です。

 
LaravelのEloquentについてもっと理解を深めたい方は PHPフレームワーク Laravel入門 をお勧めします。

ポイント
Eloquent関連の掲載ページ

Chapter 6 Eloquent ORM
6.1 Eloquent ORM
6.2 検索とスコープ
6.3 モデルの保存・更新・削除
6.4 モデルのリレーション

本庄マサノリ

仕事で Laravel を使っています。気づいたことや新しい発見など情報を発信していきます。問い合わせはこちら

>> Twitter をフォローする

 

-基礎知識