WEBOPIXEL

Laravelでリレーション先の条件で検索

Posted: 2018.07.27 / Category: PHP / Tag: 

例えばWordPressでいう、タグやカテゴリーにスラッグ情報のラカムがあったとして、リレーション元からリレーション先のカラム(スラッグ)で検索させたいときの方法をご紹介します。

Sponsored Link

Postは一つのCategoryと複数のTagを持ってるとしたい場合、モデルはこんな感じになりますね。

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
	public function category()
	{
		return $this->hasOne(Category::class, 'id', 'category_id');
	}

	public function tags()
	{
		return $this->belongsToMany(Tag::class);
	}
}

Postsコントローラーから指定したCategoryのスラッグ(slug)で検索したい場合次のようになります。

namespace App\Http\Controllers;

use App\Http\Controllers\Controller;
use \App\Models\Post;

class PostsController extends Controller
{
	public function index()
	{
		$posts = Post::whereHas('category', function($query) {
			// slugをkeywordで検索
			$query->where('slug', 'keyword');
		})->get();

		dd($posts);
	}
}

次はTagです。belongsToManyだから難しそうですね。どうなるんでしょうか。

$posts = Post::whereHas('tags', function($query) {
	$query->where('slug', 'keyword');
})->get();

dd($posts);

はい。categoryをtagsに変えるだけでした。簡単でした。

検索するキーワードはリクエストなど外部の変数を使用することがほとんどだと思います。
その場合useで外部の変数を使用できるようにします。

$keyword = 'keyword';
	$posts = Post::whereHas('tags', function($query) use ($keyword) {
		$query->where('slug', $keyword);
	})->get();
	
	dd($posts);

以上です。

LEAVE A REPLY

コードを書く場合は<pre>で囲んでください。