0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Laravel/Eloquent】モデル連携でよく使う機能まとめ

Posted at

Laravel の Eloquent ORM は、データベース操作をシンプルかつ直感的に行える強力なツールです。
この記事では、以下の内容を詳しく解説します。

  • 基本操作(レコードの取得・作成・更新・削除)
  • モデル間のリレーション(1対多、多対多、1対1)
    → 各リレーションのサンプルテーブルも提示
  • アクセサ(Accessor)とミューテータ(Mutator)
  • クエリスコープ(Query Scopes)
  • モデルイベント(Model Events)
  • その他の便利機能(ソフトデリート、ペジネーションなど)

1. 基本操作

1-1. レコードの取得

  • 全件取得

    $users = App\Models\User::all();
    
  • 条件付き取得

    $activeUsers = App\Models\User::where('active', 1)->get();
    
  • 単一レコードの取得

    $user = App\Models\User::find(1); // 主キーで取得
    // または
    $user = App\Models\User::where('email', 'example@example.com')->first();
    

1-2. レコードの作成・更新・削除

  • 新規作成

    $user = new App\Models\User();
    $user->name  = 'John Doe';
    $user->email = 'john@example.com';
    $user->save();
    
  • create メソッドによる一括作成
    ※モデル内で $fillable または $guarded の設定が必要です。

    $user = App\Models\User::create([
        'name'     => 'Jane Doe',
        'email'    => 'jane@example.com',
        'password' => bcrypt('secret')
    ]);
    
  • 更新

    $user = App\Models\User::find(1);
    $user->update(['name' => 'John Smith']);
    
  • 削除

    $user = App\Models\User::find(1);
    $user->delete();
    

2. モデル間のリレーション

Eloquent では、モデル同士のリレーションを直感的に定義できます。
以下に、代表的なリレーション(1対多、多対多、1対1)のサンプルシナリオとテーブル例、モデル定義、使用例を示します。

2-1. 1対多 (One To Many)

サンプルシナリオ

  • ユーザー (users)
    → 各ユーザーが複数の投稿 (posts) を持つ

テーブルサンプル

users テーブル

カラム名 データ型 説明
id INT (PK) ユーザーの主キー
name VARCHAR(255) ユーザー名
email VARCHAR(255) メールアドレス
created_at TIMESTAMP 作成日時
updated_at TIMESTAMP 更新日時

posts テーブル

カラム名 データ型 説明
id INT (PK) 投稿の主キー
user_id INT (FK) 投稿者のユーザーID(users.id への外部キー)
title VARCHAR(255) 投稿タイトル
content TEXT 投稿内容
created_at TIMESTAMP 作成日時
updated_at TIMESTAMP 更新日時

モデル定義

User モデル (app/Models/User.php)

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    // ユーザーは複数の投稿を持つ
    public function posts()
    {
        return $this->hasMany(Post::class);
    }
}

Post モデル (app/Models/Post.php)

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    // 投稿は1人のユーザーに属する
    public function user()
    {
        return $this->belongsTo(User::class);
    }
}

使用例

$user = App\Models\User::find(1);
$posts = $user->posts; // ユーザーID 1 の全投稿を取得

2-2. 多対多 (Many To Many)

サンプルシナリオ

  • 投稿 (posts)
    → 複数のタグ (tags) を持つ
  • タグ (tags)
    → 複数の投稿に付与できる

テーブルサンプル

posts テーブル

カラム名 データ型 説明
id INT (PK) 投稿の主キー
title VARCHAR(255) 投稿タイトル
content TEXT 投稿内容
created_at TIMESTAMP 作成日時
updated_at TIMESTAMP 更新日時

tags テーブル

カラム名 データ型 説明
id INT (PK) タグの主キー
name VARCHAR(255) タグ名
created_at TIMESTAMP 作成日時
updated_at TIMESTAMP 更新日時

post_tag 中間テーブル

カラム名 データ型 説明
post_id INT (FK) 投稿ID(posts.id への外部キー)
tag_id INT (FK) タグID(tags.id への外部キー)

モデル定義

Post モデル (app/Models/Post.php)

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    // 投稿は複数のタグを持つ
    public function tags()
    {
        return $this->belongsToMany(Tag::class);
    }
}

Tag モデル (app/Models/Tag.php)

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Tag extends Model
{
    // タグは複数の投稿に属する
    public function posts()
    {
        return $this->belongsToMany(Post::class);
    }
}

使用例

$post = App\Models\Post::find(1);
$tags = $post->tags; // 投稿に付いたタグを取得

$tag = App\Models\Tag::find(1);
$posts = $tag->posts; // タグが付いた全投稿を取得

2-3. 1対1 (One To One)

サンプルシナリオ

  • ユーザー (users)
    → 各ユーザーに1つのプロフィール (profiles) がある

テーブルサンプル

users テーブル

カラム名 データ型 説明
id INT (PK) ユーザーの主キー
name VARCHAR(255) ユーザー名
email VARCHAR(255) メールアドレス
created_at TIMESTAMP 作成日時
updated_at TIMESTAMP 更新日時

profiles テーブル

カラム名 データ型 説明
id INT (PK) プロフィールの主キー
user_id INT (FK) ユーザーID(users.id への外部キー)
bio TEXT 自己紹介文
twitter VARCHAR(255) Twitter アカウント
created_at TIMESTAMP 作成日時
updated_at TIMESTAMP 更新日時

モデル定義

User モデル (app/Models/User.php)

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    // ユーザーは1つのプロフィールを持つ
    public function profile()
    {
        return $this->hasOne(Profile::class);
    }
}

Profile モデル (app/Models/Profile.php)

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Profile extends Model
{
    // プロフィールは1人のユーザーに属する
    public function user()
    {
        return $this->belongsTo(User::class);
    }
}

使用例

$user = App\Models\User::find(1);
$profile = $user->profile; // ユーザーのプロフィールを取得

$profile = App\Models\Profile::find(1);
$user = $profile->user; // プロフィールからユーザー情報を取得

3. アクセサ (Accessors) とミューテータ (Mutators)

Eloquent では、属性値の取得時および保存時に自動的な変換を行うことが可能です。

アクセサ(取得時の変換)

// app/Models/User.php
public function getNameAttribute($value)
{
    // DB の値 "john" を "JOHN" に変換して返す
    return strtoupper($value);
}

使用例:

$user = App\Models\User::find(1);
echo $user->name; // 常に大文字で表示

ミューテータ(保存時の変換)

// app/Models/User.php
public function setEmailAttribute($value)
{
    // 保存前にメールアドレスを小文字に変換
    $this->attributes['email'] = strtolower($value);
}

使用例:

$user = new App\Models\User();
$user->email = 'John@Example.Com'; // 保存時に "john@example.com" に変換される
$user->save();

4. クエリスコープ (Query Scopes)

共通のクエリ条件をスコープとして定義することで、コードの再利用性が向上します。

ローカルスコープ

// app/Models/User.php
public function scopeActive($query)
{
    return $query->where('active', 1);
}

使用例:

$activeUsers = App\Models\User::active()->get();

グローバルスコープ

// app/Models/User.php
protected static function booted()
{
    static::addGlobalScope('active', function ($builder) {
        $builder->where('active', 1);
    });
}

5. モデルイベント

Eloquent では、モデルのライフサイクルに合わせたイベントを利用して自動処理を実行できます。

// app/Models/User.php
protected static function booted()
{
    static::created(function ($user) {
        \Log::info('新規ユーザーが登録されました: ' . $user->email);
    });
}

6. その他の便利な機能

6-1. ソフトデリート (Soft Deletes)

論理削除を行う場合、SoftDeletes トレイトを利用します。

use Illuminate\Database\Eloquent\SoftDeletes;

class Post extends Model
{
    use SoftDeletes;
    protected $dates = ['deleted_at'];
}

6-2. ペジネーション (Pagination)

大量のレコードを扱う際は、簡単にページネーションが利用できます。

$users = App\Models\User::paginate(15);

Blade テンプレートでの表示例:

{{ $users->links() }}

まとめ

Eloquent の各機能を組み合わせることで、以下のように柔軟かつ効率的なデータベース操作が実現できます。

  • 基本操作:
    レコードの取得、作成、更新、削除

  • リレーション:

    • 1対多: ユーザーと投稿の関係を hasMany/belongsTo で定義
      (例:usersposts テーブル、外部キー user_id
    • 多対多: 投稿とタグの関係を belongsToMany で定義
      (例:中間テーブル post_tag で管理)
    • 1対1: ユーザーとプロフィールの関係を hasOne/belongsTo で定義
      (例:usersprofiles テーブル、外部キー user_id
  • アクセサ/ミューテータ:
    取得時・保存時の自動変換処理

  • クエリスコープ:
    共通クエリ条件の再利用

  • モデルイベント:
    ライフサイクルに応じた自動処理(例:新規登録時のログ出力など)

  • その他の機能:
    ソフトデリート、ペジネーションなど

これらの機能を活用することで、コードの可読性と再利用性が向上し、堅牢なアプリケーションの開発が可能になります。ぜひ各プロジェクトで試してみてください!


参考リンク


以上、リレーション機能のテーブルサンプルを含む Eloquent の各機能まとめ【完全版】でした。
質問やご意見があれば、ぜひコメントしてください!

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?