- 投稿日:2019-05-30T23:56:26+09:00
Laravel-Eloquent(Mysql)で、select結果に固定値カラムを追加する方法(使用例)
mysql
select '1' as sample;Laravel
$list = SampleModel::select('id', DB::raw("'1' as sample"))->get();真偽値なんかを扱いたいときは
$list =SampleModel::select('id', DB::raw("1 = status as sample"))->get();trueは1が入り、falseの場合は0が入る。
どういったときに便利か
Sampleテーブルのカラムにstatusカラムが存在し、そのstatusの中身が1,2,3だった場合、1の時はこのボタンを表示したいんだけどなぁとか思ったときに、カラムを足さない場合は、
blade@foreach($list as $item) @if((int)$item->status === 1)といったような文を書くことがあるとします。この形は、Viewのほうには、なるべくロジックを加えたくないし、1は何を示しているのかわかりません。そのために、SampleModelに定数を定義します。
SampleModel.phpconst STATUS_HAPPY = 1; const STATUS_SAD = 2;bladeを修正します。
blade@if((int)$item->status === \App\Models\SampleModel::STATUS_HAPPY)これで、statusがHappyの時は、なにかするんだなとわかりやすくなりましたが、if分の中が長くなってしまいました。そのため、データにstatusがhappyかどうかのフラグを持たせる処理を作ってみます。
$list = SampleModel::select('id', 'status')->map(function ($row){ $row->is_happy = ((int)$row->status === SampleModel::STATUS_HAPPY); });blade@if($item->is_happy)先ほどより、bladeのほうの処理は、短くなりよくなりました。ただ、phpの処理のほうをis_happyだけのために、mapを回したく無く感じますので、selectでとっちゃいます。
$list = SampleModel::select('id', 'status', DB::raw(SampleModel::STATUS_HAPPY. ' = status as is_happy'))->get();これで、statusカラムの中身とSampleModel::STATUS_HAPPYが一致した場合はis_happyは1で、一致しない場合は0が入りますので、
bladeでそのまま使えます。blade@if($item->is_happy)アクセサを使った書き方
ありがたいコメントをいただきましたので、追記させていただきます。
Laravelには、アクセサ(カラム定義)機能がありまして、getカラム名Attribute()で取得するカラムのフォーマットを定義したり、もともと存在しないカラムを追加することができます。// SampleModel public function getIsHappyAttribute() { return (int)$this->status === static::STATUS_HAPPY; } // controller $list = SampleModel::select(['id', 'status'])->get(); // blade @foreach ($list as $item) @if ($item->is_happy)注意点としましては、SampleModel::select(['id', 'status'])->get()をforeachで回した際は、is_happyは取得できますが、toArray()を使ってしまうと、is_happyを取得できなくなります。
まとめ
アクセサを使う方法が1番、それでもダメな特殊ケースの場合のみ、DB::rawを使って、カラムを付け加える方針で今後やってこうと思います。
- 投稿日:2019-05-30T23:32:00+09:00
Laravel 2つの異なるテーブルを合わせて、ページネーションをかける
Apple・Lemonテーブル
public function test(Request $request) { $subQuery = Apple::from('apples as A') ->select('A.id', 'A.name'); $list = Lemon::from('lemons as L') ->select('L.id', 'L.name') ->UnionAll($subQuery) ->orderBy('name', 'asc') ->paginate(10); return view('test', [ 'paginate' => $list, ] ); }unionは、重複を削除します。UnionAllは重複を削除しません。
union allコストについて参考記事異なるDBを見たい場合
public function test(Request $request) { $subQuery = Apple::from('sample1.apples as A') ->select('A.id', 'A.name'); $list = Lemon::from('sample2.lemons as L') ->select('L.id', 'L.name') ->UnionAll($subQuery) ->orderBy('name', 'asc') ->paginate(10); return view('test', [ 'paginate' => $list, ] ); }テーブルの前にDB名.で指定すると別々のDBを見に行ってくれます。