先の記事で、標準の認証機能を使用したが、認証情報に他テーブルのデータも保持しおきたいと思い、調べてみましたがちょっとやり方が違うのか手こずりました。
クライアント環境:Windows10 XAMPP(PHP7.0.4) Eclipse 4.5.2(Mars) Laravel5.2.39
サーバ環境:CentOS7 MariaDB5.5.47
調べてみる!
Google先生に「laravel5 auth user join」で聞いてみた。
http://ja.stackoverflow.com/questions/11271/laravel-5-の-authuser-のプロパティにjoinしたデータを追加したい
おぉ!stackoverflow先生まで日本語版が出てきたのね。と思いながらそのままやってみる。
ダメだった!まぁそんなもんです。日本語版が無いときもそんなもんです。いい線は行くのは間違いないので、stackoverflow先生も必要なんですよ。そのものズバリってのは面白く無い!(工数の問題はともかくとして…)
結果
私の愚痴なんてどうでもいいので、結果はこんな感じ。
まずは、認証クラスをオーバーライドして発行されるSQLを変更するために、プロバイダを作る。
<?php
namespace App\Providers;
use Illuminate\Auth\EloquentUserProvider;
class AuthUserProvider extends EloquentUserProvider
{
public function retrieveById($identifier) {
$result = $this->createModel()->newQuery()
->leftJoin('corps', 'users.corp_id', '=', 'corps.id')
->leftJoin('shops', 'users.shop_id', '=', 'shops.id')
->select(['users.*', 'corps.name as corp_name', 'shops.name as shop_name'])
->find($identifier);
return $result;
}
}
そのユーザの所属している法人名と店舗名をJOINした結果を取得する感じですね。
次、上記のクラスを認証ドライバとして追加します。
<?php
namespace App\Providers;
use Illuminate\Contracts\Auth\Access\Gate as GateContract;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
use App\Providers\AuthUserProvider;
use Auth;
class AuthServiceProvider extends ServiceProvider
{
/**
* The policy mappings for the application.
*
* @var array
*/
protected $policies = [
'App\Model' => 'App\Policies\ModelPolicy',
];
/**
* Register any application authentication / authorization services.
*
* @param \Illuminate\Contracts\Auth\Access\Gate $gate
* @return void
*/
public function boot(GateContract $gate)
{
$this->registerPolicies($gate);
//
}
public function register() {
Auth::provider('auth_ex', function($app) {
// スタックオーバーフロー先生はこれで取れると書いてあるんだけど、モデルが取れない…
// $model = $this->app['config']['auth.model'];
$model = $app['config']['auth.providers.users.model'];
return new AuthUserProvider($app['hash'], $model);
});
}
}
register()メソッドは無いので追加してあげます。
モデルの取得があれでいいのかはだいぶ微妙な書き方だなと。もうちょっと良いやり方があれば教えてください。
次、’auth_ex’を定義してあげないといけません。
<<省略>>
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\User::class,
],
'users' => [
'driver' => 'auth_ex',
'model' => App\User::class,
],
// 'users' => [
// 'driver' => 'database',
// 'table' => 'users',
// ],
],
<<省略>>
以上、これで「Auth::user()->shop_name」ってやると店舗名が取得できたりします。