例えば、データベースに登録する際、どのユーザーが登録したかを記録しておきたい場合、もしくは、登録したユーザーのみ閲覧・編集・削除を可能にしたい場合などには、誰がデータを登録したのかログイン中のuser_idを内容と一緒に保存する必要があります。
しかし、Laravelのマニュアルに従った方法では、毎回登録時にuser_idを挿入する処理を書かなければなりません。
そこで、Laravelのモデルに定義されているイベントとグローバルスコープ(addGlobalScope関数)を使ってこれらを解決していきます。
Traits(トレイト)を作成する
トレイトとは、PHP 5.4.0 以降で導入されたコードを再利用するための仕組みです。
ここに登録と検索の際に使用するコードを書いておきます。
トレイトは、PHP のような単一継承言語でコードを再利用するための仕組みのひとつです。
PHP: トレイト – Manual
トレイトは、単一継承の制約を減らすために作られたもので、 いくつかのメソッド群を異なるクラス階層にある独立したクラスで再利用できるようにします。
トレイトとクラスを組み合わせた構文は複雑さを軽減させてくれ、 多重継承や Mixin に関連するありがちな問題を回避することもできます。
さて、まずはuser_idを登録・検索する処理を作成していきましょう。
App\Userable.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
<?php namespace App; use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Model; trait Userable { public static function bootUserable() { static::addGlobalScope('mine', function(Builder $builder) { $builder->where('user_id', auth()->id()); }); static::creating(function (Model $model) { $model->user_id = auth()->id(); }); } } |
ココだけを見ると、モデルにboot()で書けばいいじゃん?と思ったかもしれませんが、複数のモデル(テーブル)にも同じことがしたい場合はトレイトを使った方が便利です。
そして、それぞれのモデルにuseして継承します。
ユーザーIDを使用する際の注意点
addGlobalScope関数を利用する際に、かなりハマってしまったのですが、ログイン中にも関わらずauth()
がNULLになって、正常にデータを取得できませんでした。
原因はProvidersAppServiceProvider.php
でView::share()
しているモデルでこのトレイトを使おうとしたから。
こんな感じで。
1 |
View::share('persons', Person::pluck('name', 'id')); |
どうやらプロバイダー内ではログイン情報を持っていないらしい。
ちなみに、Auth::id()
でもダメだよ。
悩んだ末、最終的にはミドルウェアでView::share()
するように修正した。
App\Person.php(通常モデル)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
<?php namespace App; use Illuminate\Database\Eloquent\Model; use App\Userable; class Person extends Model { use Userable; /** * The database table used by the model. * * @var string */ protected $table = 'persons'; /** * The database primary key value. * * @var string */ protected $primaryKey = 'id'; /** * Attributes that should be mass-assignable. * * @var array */ protected $fillable = ['name']; } |
これだけで、insertする場合にはuser_idも自動で登録、selectする場合には検索条件にwhere user_id = [ログイン中のID]を自動で入れてくれます。
また、creating以外にもイベントが用意されているので、updateやdeleteをする際にも自動で何らかの処理を挿入することができます。
定義されているイベント一覧
イベント名 | 説明 |
---|---|
creating | 作成するとき |
created | 作成したとき |
updating | 更新するとき |
updated | 更新したとき |
saving | 保存するとき(制作でも、更新でも) |
saved | 保存したとき(制作でも、更新でも) |
deleting | 削除するとき |
deleted | 削除したとき |
restoring | ソフト削除をレストアするとき |
restored | ソフト削除をレストアしたとき |
皆さんありがとうございます。お世話になっています。
コメント
コメント一覧 (2件)
[…] 以前、Laravelでトレイトを使ってuser_idの自動登録や常に検索条件に含ませる方法を紹介しました。 今回はそれの応用で、DB登録時に常に暗号化して、表示する際は必ず復号化する方法をご紹介します。 特に個人情報やパスワードなどの重要なデータを取り扱う場合には非常に有効で、セキュリティの向上にも繋がりますので、覚えていて損はないかと思います。 【Laravel】DB登録で必ずuser_idを入れ、検索は自動でuser_idを含ませる方法https://minory.org/laravel-userable.html例えば、データベースに登録する際、どのユーザーが登録したかを記録しておきたい場合、もしくは、登録したユーザーのみ閲覧・編集・削除を可能にしたい場合などには、誰がデータを登録したのかログイン中のuser_idを内容と一緒に保存する必要があります。しかし、La… Minory (adsbygoogle=window.adsbygoogle||[]).push({}); […]
[…] 以前、LaravelでTraits(トレイト)を利用してスコープの追加(addGlobalScope())をご紹介した記事を覚えているでしょうか? 単純な会員制のCRUDなら良いのですが、自分自身が登録したものしか表示されないので、会員が作成したものを全体に公開するような場合は、データベースから取得する際に普段のクエリに1ワード加えます。 【Laravel】DB登録で必ずuser_idを入れ、検索は自動でuser_idを含ませる方法https://minory.org/laravel-userable.html例えば、データベースに登録する際、どのユーザーが登録したかを記録しておきたい場合、もしくは、登録したユーザーのみ閲覧・編集・削除を可能にしたい場合などには、誰がデータを登録したのかログイン中のuser_idを内容と一緒に保存する必要があります。しかし、La…Minory 1 share 1 user 2 pockets […]