[PHP][Laravel][SQL] LaravelのEloquentで WHERE A OR B を実施(条件によりorWhere条件を追加)

バージョン

Laravel 6.0

概要

Eloquentで以下を表現する。

WHERE (hoge = 1 AND fuga = 2) OR (foo = 3 AND bar = 4)

さらにOR条件は条件分岐により追加する/しないを判断させる。

実現したいSQL

SELECT
  students.name, clubs.name
FROM
  students
LEFT JOIN
  clubs ON students.club_id = clubs.id AND clubs.code = 4
WHERE
  (students.grade > 5 and clubs.type = 1)
  OR
  (students.grade in (1,3) and students.area_code = 10)
ORDER BY
  students.created_at desc

Models/student.php

$query = self::select(['students.name as students_name', 'clubs.name as clubs_name'])
        ->leftjoin('clubs', function ($join) {
            $join->on('students.club_id', '=', 'clubs.id')
                >where('clubs.code', config('club.code.D'));
            })
        ->where(function ($q) use ($grade) {
            $q->orWhere('students.grade', '>', $grade)
                >where('clubs.type', config('club.type.BUNKAKEI'));
            });

if ($grades) {
    $query = $query->orWhere(function ($q) use ($grades) {
        $q->orWhereIn('students.grade', $grades)
            ->where('students.area_code', config('students.area_code.TOKYO'));
    });

return $query->orderBy('students.created_at', 'desc')
    ->get()
    ->toArray();
}



PHPフレームワーク Laravel実践開発

PHPフレームワーク Laravel実践開発

[SQL] 条件(カラムの値)によってJOIN対象のテーブルを変える

概要

Aテーブルのカラム値によってJOINするテーブルをBテーブルまたはCテーブルのどちらかにする。
例)
salesテーブルのsale_typeが1の場合はusersテーブルのnameを、
sale_typeが2の場合はcustoersテーブルのnameを取得する。

テーブル定義

// saleテーブル
CREATE TABLE `sales`
(
  `id` INT UNSIGNED AUTO_INCREMENT,
  `sale_type` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '販売タイプ(1:ユーザー、2:得意先)',
  `target_id` INT UNSIGNED NOT NULL COMMENT '対象ID',
  `price` INT COMMENT '金額',
  PRIMARY KEY (`id`)
}

// usersテーブル
CREATE TABLE `users`
(
  `id` INT UNSIGNED AUTO_INCREMENT,
  `name` varchar(20) NOT NULL COMMENT 'ユーザー名称',
  PRIMARY KEY (`id`)
}

// customersテーブル
CREATE TABLE `customers`
(
  `id` INT UNSIGNED AUTO_INCREMENT,
  `name` varchar(20) NOT NULL COMMENT '得意先名称',
  PRIMARY KEY (`id`)
}

SQL

SELECT sales.*, users.name as user_name, customers.name as customer_name
  FROM sales
  LEFT JOIN users ON users.id = sales.target_id AND sales.sale_type = 1
  LEFT JOIN customers ON customers.id = sales.target_id AND sales.sale_type = 2

LEFT JOINのON条件で絞り込んでしまえば良い。
これをしないと不適切なデータが取れてしまい、場合によっては情報漏洩にも繋がりかねない。



SQLアンチパターン

SQLアンチパターン

  • 作者:Bill Karwin
  • 発売日: 2013/01/26
  • メディア: 大型本

[PHP][Laravel] Laravelの条件付きvalidation(入力値を判定してバリデーションを追加するか判断する)

バージョン

Laravel 6.0

概要

例えば、A項目の値がtrueだった時のみB項目を必須項目にするといったケース。

コード

■HogeRequest.php

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        $data = $this->all();

        return self::getRules($data['data_A']);
    }

    public static function getRules($data_a)
    {
        // 共通的なバリデーション
        $rules = [
            'price'        => 'required|integer|min:0',
            'remarks'   => 'max:100',
        ];

        if ($data_a) {
            // data_Aがtrueだった時のみdata_Bを必須に
            $rules['data_B'] = 'required';
        }

        return $rules;
    }

単一カラムでの条件付きバリデーションは「laravel validation sometimes」で検索を。



速習 Laravel 6 速習シリーズ

速習 Laravel 6 速習シリーズ

[PHP][Laravel] LaravelのEloquentで更新前の値を取得

バージョン

Laravel 6.0

概要

Eloquentでレコード更新(save)前に更新対象と変更前の値を取得する。
その他にも変更前情報関連のサンプルコードを記載する。

コード

    $user_info = UserInformation::find($user_id);

    $user_info->name = '山田太郎';
    $user_info->status = 4;

     // 変更前ステータス
    $before_status = $user_info->getOriginal("status");
    // 全ての変更前値をみたい
    $dirty = $user_info->getDirty();
    foreach ($dirty as $field => $new_data)
    {
        $old_data = $user_info->getOriginal($field);
    }

    // 変更対象数の確認
    if (count($dirty) > 0){
        // 変更対象がある
        $user_info->save();
    }



速習 Laravel 6 速習シリーズ

速習 Laravel 6 速習シリーズ

[vue.js][Javascript] 配列、連想配列の要素数を取得

概要

Javascriptで要素数を取得する。
連想配列は.lengthでは取得できないので注意。

配列:ary.length
連想配列:Object.keys(arylist).length

コード

◾️hoge.vue

  let ary = ['a', 'b', 'c'];
  alert(ary.length);   // 3

  let arylist = [];
  arylist['a'] = 1;
  arylist['b'] = 11;
  arylist['c'] = 2;
  arylist['d'] = 22;
  alert(Object.keys(arylist).length);  // 4



JavaScript 第6版

JavaScript 第6版

[PHP][Laravel] JSON内の値(複数行)をバリデーションする

バージョン

Laravel 5.8

概要

JSONで渡された複数行のデータに対してバリデーションする。 例として以下のJSONに対して、バリデーションを実施する。
◾️JSON

[{"id": 1, "val": "abcde"}, {"id": 2, "val": "あいうえお"}, {"id": 3, "val": ""}]

◾️バリデーションルール

  1. データは10項目まで
  2. valは必須で100文字以内

コード

◾️HogeController

    public function HogeInput(Request $request)
    {
        // JSONをデコード
        $validation_data = json_decode($params['json_val'], true);
        
        // バリデーション
        // データ数の検証
        $rules = [
            'remarks' => 'array|max:10'
        ];
        $validator = Validator::make(['remarks' => $validation_data], $rules);
        if ($validator->fails()) {
            return response()->error($validator->errors()->all());
        }

        // 各行の検証
        foreach ($validation_data as $key => $value) {
            $rules = [
                'val' => 'required|max:100'
            ];
            $validator = Validator::make($value, $rules);
            if ($validator->fails()) {
                return response()->error($validator->errors()->all());
            }
        }

    }



PHPフレームワークLaravel入門 第2版

PHPフレームワークLaravel入門 第2版

[PHP][Laravel] ログイン後のリダイレクト先を変更する

バージョン

Laravel 5.8

概要

ログイン後に遷移するリダイレクト先を例えばダッシュボード画面(/dashboard)にしたい。

コード

◾️LoginController

class LoginController extends Controller
{
    use AuthenticatesUsers;

    /**
     * Where to redirect users after login.
     *
     * @var string
     */
    protected $redirectTo = '/dashboard';

}

LoginController.phpの$redirectToをオーバーライドしてリダイレクト先を指定すればよい。



PHPフレームワークLaravel入門 第2版

PHPフレームワークLaravel入門 第2版