5
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Laravel Eloquentでリレーション先のリレーションを取得

Posted at

#概要
Eloquentでリレーション先のデータを取得することがありますが、リレーション先のリレーションのデータが欲しい時に手こずったのでやり方をメモします。

#構成
今回はユーザーがいいねしている投稿データを取得したいと思います。

##テーブル構成

mysql> desc users;
+-------------------+-----------------+------+-----+---------+----------------+
| Field             | Type            | Null | Key | Default | Extra          |
+-------------------+-----------------+------+-----+---------+----------------+
| id                | bigint unsigned | NO   | PRI | NULL    | auto_increment |
| name              | varchar(255)    | NO   |     | NULL    |                |
| email             | varchar(255)    | NO   | UNI | NULL    |                |
| email_verified_at | timestamp       | YES  |     | NULL    |                |
| password          | varchar(255)    | NO   |     | NULL    |                |
| remember_token    | varchar(100)    | YES  |     | NULL    |                |
| created_at        | timestamp       | YES  |     | NULL    |                |
| updated_at        | timestamp       | YES  |     | NULL    |                |
+-------------------+-----------------+------+-----+---------+----------------+
8 rows in set (0.05 sec)

mysql> desc favorites;
+-------------+-----------------+------+-----+---------+----------------+
| Field       | Type            | Null | Key | Default | Extra          |
+-------------+-----------------+------+-----+---------+----------------+
| favorite_id | bigint unsigned | NO   | PRI | NULL    | auto_increment |
| user_id     | bigint unsigned | NO   | MUL | NULL    |                |
| post_id     | bigint unsigned | NO   | MUL | NULL    |                |
| created_at  | timestamp       | YES  |     | NULL    |                |
| updated_at  | timestamp       | YES  |     | NULL    |                |
+-------------+-----------------+------+-----+---------+----------------+
5 rows in set (0.01 sec)

mysql> desc posts;
+-------------+-----------------+------+-----+---------+----------------+
| Field       | Type            | Null | Key | Default | Extra          |
+-------------+-----------------+------+-----+---------+----------------+
| post_id     | bigint unsigned | NO   | PRI | NULL    | auto_increment |
| user_id     | bigint unsigned | NO   | MUL | NULL    |                |
| description | longtext        | NO   |     | NULL    |                |
| photo_name  | varchar(255)    | NO   |     | NULL    |                |
| photo_path  | varchar(255)    | NO   |     | NULL    |                |
| created_at  | timestamp       | YES  |     | NULL    |                |
| updated_at  | timestamp       | YES  |     | NULL    |                |
+-------------+-----------------+------+-----+---------+----------------+
7 rows in set (0.00 sec)

usersテーブル:ユーザ情報
favoritesテーブル:投稿に対してのいいね情報
postsテーブル:ユーザーが投稿した記事情報

##Model
###User

User.php
<?php

namespace App\Models;

use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Sanctum\HasApiTokens;

class User extends Authenticatable
{
    use HasApiTokens, HasFactory, Notifiable;
    protected $fillable = [
        'name',
        'email',
        'password',
        'login_id',
    ];
    protected $hidden = [
        'password',
        'remember_token',
    ];
    protected $casts = [
        'email_verified_at' => 'datetime',
    ];

    public function post()
    {
        return $this->hasMany('App\Models\Post');
    }

    public function favorite()
    {
        return $this->hasMany('App\Models\Favorite');
    }
}

###Post

Post.php
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    use HasFactory;

    protected $fillable = [
        'user_id',
        'description',
        'photo_name',
        'photo_path'
    ];
    protected $primaryKey = 'post_id';

    public function user()
    {
        return $this->belongsTo('App\Models\User');
    }
    public function favorite()
    {
        return $this->hasMany('App\Models\Favorite', 'post_id');
    }
}

###Favorite

Favorite.php
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Favorite extends Model
{
    use HasFactory;

    protected $fillable = [
        'user_id',
        'post_id',
    ];
    protected $primaryKey = "favorite_id";

    public function user()
    {
        return $this->belongsTo('\App\Models\User', 'user_id');
    }
    public function post()
    {
        return $this->belongsTo('App\Models\Post', 'post_id');
    }
}

##Controller

FavoriteController.php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\User;

class FavoriteController extends Controller
{
    //ユーザーがいいねした投稿を取得する
    public function getMyFavorite(Request $request)
    {
        $favorites = User::with(['favorite' => function ($query) {
            $query->with('post');
        }])->find($request->user_id);
        return response()->json(['favorites' => $favorites], 200);
    }
}

###まとめ
もっといい方法がある気もしますが、とりあえずはこれで引っ張ってこれました。

5
6
1

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
5
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?