株のポートフォリオを管理できるwebアプリを自作していた時、バリデーションで詰まったので備忘録として記事に記します。
OS mac10.13
PHP7.1.14
laravel 5.6
目的
各銘柄(≒企業名)には、独自の「証券コード」があります。
IDのようなものだと考えていただいて結構です。
株のポートフォリオを組む時、この証券コードが重複したら変なのでそのチェックが目的です。
(銘柄名も重複したらおかしいので、これもチェック)
調べた結果・・・
unique
というバリデーションルールがlaravelにありました。
基本的には、unique:テーブル,カラム
というように第一引数にテーブル名・第二引数にカラム名を指定して、同一の値が無いかチェックします。
(そのカラムに同じ値があればNG,異なればOK)
ただ、これ通り使うと、Aさんが登録した銘柄をBさんが登録出来なくなってしまいます。
//stock_codeは、証券コードの意
//stocksは、証券コードや銘柄名が登録されているテーブル
'stock_code' => 'unique:stocks,stock_code'
そのため、ドキュメントには「アカウントIDが1である場合にのみチェックする」という例も載せてくれています。
'email' => Rule::unique('users')->where(function ($query) { return $query->where('account_id', 1); })
私が詰まったのはここからで、「アカウントIDが1」ではなく現在のユーザーIDの指定方法でした。
色々と調べた結果、以下の解決方法を導きました。
解決方法
stocks
テーブルにはuser_id
カラムがセットされ、users
テーブルとリレーションされています。
例↓
id | user_id | stock_code |
---|---|---|
1 | 1 | 2162 |
2 | 2 | 9433 |
もう一度目的を書くと、user_id
1の人が証券コード9433を入力出来るようにして且つ、2162を入力出来ないようにさせたいです。
なので、where句で以下のように書きます。
'stock_code' => [
Rule::unique('stocks')->where(function ($query) {
return $query->where('user_id', $this->user()->id); }),
],
user_id
と現在のユーザーのIDを照合しているという形になりますね!
これで目的が達成されました!!