#概要
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);
}
}
###まとめ
もっといい方法がある気もしますが、とりあえずはこれで引っ張ってこれました。