3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

laravel4: モデルでバリデーション

Last updated at Posted at 2013-06-03

毎度、バリデーションのルールを書くの面倒だなーということで テーブルのスキーマに合わせて自動でバリデーションすればいいじゃん!ということで作ってみた。

Dbwapper.php
use Illuminate\Database\Eloquent\Model as Eloquent;
use Illuminate\Config\Repository;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Validator;

abstract class Dbwapper extends Eloquent {
    public static function columns_info()
    {
        $instance = new static;
        $prefix = Config::get('database.connections.mysql.prefix');
        $table = $instance->table;
        if ( Cache::has( "$prefix$table" ) ){
            return unserialize( Cache::get( "$prefix$table" ) );
        } else {
            $info = DB::select("SHOW FULL COLUMNS FROM `$prefix$table`");
            $serialize = serialize($info);
            Cache::forever( "$prefix$table", $serialize ) ; 
            return $info ;
        }
    }
    /**
        Make validation rules
    **/
    public static function validate_rules()
    {
        $rules = array();
        $columns = static::columns_info();
        foreach ( $columns as $column ){
            $type       = $column->Type;
            $fieldname  = $column->Field;
            preg_match('/\(([0-9]{1,10})\)/', $type, $match);
            if ( $match ) $length     =  $match[1] ;
            $type       = mb_ereg_replace("\(.*?\)|(.*?)", "", $type);
            $required   = $column->Null == 'NO' 
                && strlen($column->Default) == 0 ? 'required|' : '';
            
            if ($column->Key == 'PRI' && $column->Extra == 'auto_increment'){
                // auto_increment の時は チェックしない
            } else {
                switch ($type){
                    case "int":
                        $rules[$fieldname] = "${required}integer";
                        break;
                    case "varchar":
                        switch ($fieldname) {
                            case "email" :
                                $rules[$fieldname] = "${required}email";
                                break;
                            // カラム名で何か特別なバリデーションルールがあればここに追加
                            //とりあえず Emailだけ
                            default:
                                $rules[$fieldname] = "${required}max:". $length;
                                break;
                        }
                        break;
                    case "datetime":
                        $rules[$fieldname] = "${required}match:/^\d{4}\-\d{2}\-\d{2} \d{2}\:\d{2}/";
                        break;
                    case "text":
                        $rules[$fieldname] = "${required}min:0";
                        break;
                    case "timestamp":
                        break;
                    case "longtext":
                        $rules[$fieldname] = "${required}min:0";
                        break;
                    case "tinyint":
                        $rules[$fieldname] = "${required}integer";
                        break;
                    case "float":
                        $rules[$fieldname] = "${required}numeric";
                        break;
                    case "date":
                        $rules[$fieldname] = "${required}match:/^\d{4}\-\d{2}\-\d{2}$/";
                        break;
                    default:
                        break;
                }
            }
        }
        return $rules;
    }

    /** 
        Auto Validate
    **/
    public static function validate($input=null,$rules=null)
    {
        // ルールが無い時は Schemaを元にrule作成
        if ( is_null($rules) )
        {
            $rules = static::validate_rules();
        }
        if ( is_null($input) ) $input = Input::all();
        
        // ルールにあるFIELD だけ Requestデータを取得
        $requests = array();
        foreach ($rules as $key => $val){
            if (array_key_exists($key,$input)){
                $requests[$key] = $input[$key];
            } else {
                $requests[$key] = null;
            }
        }
        return Validator::make($requests, $rules);
    }
}

そんで 以下の Eloquent を

app/models/User.php
class User extends Eloquent {
    protected $table = 'user';
}

Dbwapper に変える。

app/models/User.php
class User extends Dbwapper {
    protected $table = 'user';
}

Controllerで 以下の用にすれば ルールをいちいち作んなくていいかも。

$v = User::validate(Input::all());
if ($v->valid()) { 
// OK パターン
}
3
3
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?