Ich habe hunger

あふりかエンジニア、アフリカ向けのB2BのSaaSを開発する

Laravel4でリレーション先のテーブルのカラムに対してLIKE句を使う方法

よくあるWebアプリケーションでFacebookログインして、ユーザー登録させて、Facebookから情報引っ張って来てる状態を想定してます。

前提条件

各モデルは以下のようなものを想定します。

  • Userモデル

後述するFacebookUserモデルをhasOneしてます。
このモデルを中心にProfileとか○○Historyとか色々リレーションをつなげて行きます。

  • FacebookUserモデル

facebookから取得して来た情報、主に名前や性別を保持しています。
fitst_name, last_nameというカラムで持っているとします。

利用シーン

管理画面でユーザー一覧を確認出来ます。100件とかになってくると20個ずつページネーションさせてると結構しんどいので、ユーザーの名前で絞り込み検索をかけたいです。

名前はFacebookUserモデルのfirst_name, last_nameの区別なく検索される機能が想定されます。

元のコード

	public function index()
	{
		$users = User::paginate(20);

		return View::make('admin.users.index', compact('users'));
	}

普通のページネーションのやつ

リレーション持ってるやつだけ取ってくる場合

$users = User::has('facebookUser')->paginate(20);

ってやるとfacebookUserテーブルのレコードをhasOneしてるものだけ取って来れる。
ただ、今回はユーザーデータを想定しているので全然関係ない。
これを使うシーンとしては、コメントがついてるPostだけ取ってくる場合とかに使う。

その場合だと

$posts = Post::has('comment')->get();

みたいになる。

リレーション先のものに条件をつけて取得する場合

例えば、今回のようにfacebookUserテーブルのあるカラムに対する条件で検索したい場合はwhereHasを利用する。

$user = User::whereHas('facebookUser', function($q){
  $q->where('first_name', 'LIKE', '%杉山%');
})->paginate(20);

このパカッと開けたfunctionの中で、さらにwhereを書いてあげると中でしっかり絞れるのでこれ利用するとLIKE句バッチリ使えます。

first_nameだけでなく、last_nameで書く場合はorで繋いであげるとおっけー₍₍⁽⁽(ી(*゚▽゚*)ʃ)₎₎⁾⁾
あと、究極的にはwhereRawで生SQL書いてあげるってのも良いけど、外部からの入力を用いる場合はインジェクションとかに気をつけてください。

ノシノシ