laravel5.1で、プルダウンの都道府県コードをconfig.phpで持つか、テーブルで持つか検討してみた。
laravelで定数を定義する場合は、configフォルダ内に「好きな名前.php」で記述出来る。
config/pref.php
1 2 3 4 5 6 7 8 9 |
<?php return[ ''=>'', '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'=>'鳥取県','32'=>'島根県','33'=>'岡山県','34'=>'広島県','35'=>'山口県','36'=>'徳島県','37'=>'香川県','38'=>'愛媛県','39'=>'高知県','40'=>'福岡県','41'=>'佐賀県','42'=>'長崎県','43'=>'熊本県','44'=>'大分県','45'=>'宮崎県', '46'=>'鹿児島県', '47'=>'沖縄県' ]; |
// 使う時には、ファイル名と配列番号をドット区切りで指定する
echo \Config::get(‘pref.1’); // 北海道 と表示される
あっさりと出来るのが魅力だけど、Usersテーブルの住所都道府県フィールドには、1という値が入っているだけなので、SELECTで検索できない!
と、なると素直にprefテーブルを生成するしか無いけど、プルダウンの種類だけテーブル追加するのもな~。
性別(男性・女性)とか利用可・利用不可みたいな、2レコードしかないようなテーブルは作りたくない!
そこで、OTLT(One True Lookup Table)という考え方が出てきます。
http://gihyo.jp/dev/serial/01/sql_academy2/000301
種別・コード・名称の3カラムだけの単純なテーブルを1個つくればOK!
種別カラム=テーブル名(種類)という考えですな。
よし、これで行こう!と思ったけどEloquentだと外部キー1つしか選べない…。
しょうがないので、取得時にJOIN句で結合して、where句で種別カラム指定すれば、検索対象にしよう。
まずは、config/pref.php と Config::get(‘pref’) をテーブルに置き換えられるようにしてみた。
やる事は、以下の通り。多い(^_^;)
1, テーブルを生成(php artisan make:migration create_words_table –create=words)
2, テーブルのクラス生成(php artisan make:model Word)
3, サービスプロバイダーを作成(php artisan make:provider WordServiceProvider)
4, サービスプロバイダーの設定( $this->app->bindとか)
5, ファサードクラスを作成()
6, ファサードエリアスの設定
7, ファサードを使ってみる
1, テーブルを生成(php artisan make:migration create_words_table –create=words)
1 2 3 4 5 6 7 8 9 10 |
public function up() { Schema::create('words', function (Blueprint $table) { $table->increments('id'); $table->string('type'); $table->integer('code'); $table->string('name'); $table->timestamps(); }); } |
2, テーブルのクラス生成(php artisan make:model Word)
テーブルの内容を配列で返す関数を作っておく
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 32 |
<?php namespace App; use Illuminate\Database\Eloquent\Model; class Word extends Model { public static function get_data($type, $code='') { // indexの指定がなければ、指定されたtypeの全要素を配列で返す if($code==''){ $words = Word::where('type', '=', $type)->get(); $arr_word = array(); foreach($words as $word){ $arr_word += [$word->code => $word->name]; } return $arr_word; // indexの指定がされていたら、指定されたtypeの1要素の名称だけ返す }else{ $word = Word::where('type', '=', $type)->where('code', '=', $code)->get(); // 見つからない場合は空文字を返す。 if(count($word) == 0){ return ""; }else{ return $word[0]->name; } } } } |
そのままだと、blade.phpで使えないのでサービスプロバイダ化してみる(Controller側から渡すなら、やらなくても良い)
3, サービスプロバイダーを作成(php artisan make:provider WordServiceProvider)
app/Providers/WordServiceProvider.phpが生成される
4, サービスプロバイダーの設定
1 2 3 4 5 6 7 8 9 |
// App/Word.phpを結びつける。 public function register() { // App\Word.phpを登録する! $this->app->bind( 'Word', 'App\Word' ); } |
5, ファサードクラスを作成(artisanでは作れない?)
app/Facades/Word.phpを自分で生成。
1 2 3 4 5 6 7 8 9 10 11 |
<?php namespace App\Facades; use Illuminate\Support\Facades\Facade; class Word extends Facade { protected static function getFacadeAccessor() { return 'Word'; } } |
6, ファサードエリアスの設定
config/app.phpに、プロバイダとエイリアスを設定
1 2 3 4 5 6 |
'providers' => [ App\Providers\WordServiceProvider::class, ] 'aliases' => [ 'Word' => App\Facades\Word::class, ], |
7, ファサードを使ってみる
edit.blade.php
1 2 |
{!! Form::select('prefecture', Word::get_data('pref')) !!} // 都道府県プルダウンが表示される。 {!! Word::get_data('pref', 1) !!} // 北海道、という文字列が表示される。 |
これで、Config::get(‘pref’)と同じように使えるし、DBテーブル1つで管理・運用できる!
bladeファイルで、テーブルのプルダウンを表示したいだけなのに一苦労だな…。
めんどくせえ、めんどくせえ、マウスをクリックすらめんどくせえ~。
参照URL: https://laravel10.wordpress.com/2015/04/27/%E3%83%95%E3%82%A1%E3%82%B5%E3%83%BC%E3%83%89/
ようやくフリーワード検索の所が作れるようになった。
app/Http/UsersController.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 |
use App\Word; public function index() { // Userインスタンス生成 $query = User::query(); // GET引数から検索フリーワードを変数に格納 $search_word = \Input::get('search_word'); if(!empty($search_word)){ //テーブル名は別名prefにしておく(同じテーブルで、type毎に切り分ける) $query->leftjoin('words as pref', 'pref.code', '=', 'users.prefecture'); $query->where('pref.type', '=', 'pref'); // emailと都道府県名(結合先)のどちらかにヒットしたレコードを取得するwhere句 $query->where('email', 'like', '%'. $search_word .'%') // 都道府県もフリーワード検索対象にする ->orwhere('pref.name', 'like', '%'. $search_word .'%') } // wordsテーブルを結合したので、idカラムが重複する対策!(bladeでは、users_idで指定する) $query->select('*','users.id as users_id'); //レコード取得 $users = $query->get(); // bladeに渡す return view('users.index')->with(compact('users')); } |