全ての View で 何かの件数を表示したい時、ミドルウェアを作ったり、コントローラーを継承した親コントローラーに 共通処理を書いてもいいのですが、直接モデルオブジェクトを呼ぶという方法もあります。
Blade の ビューファイル から直接呼び出します。
例
自分の記事数 : {{ \App\MyArticle::count() }}
自分のユーザー数 : {{ \App\MyUser::count() }}
同様に static なメソッドを作成すれば、どこからでも呼ぶことができます。
app/Http/Controllers/MyController.php
public static function getMyCount() {
// ここに何かの処理
$result = 99999;
return $result;
}
ビューからはこのように呼び出せます。
{{ \App\Http\Controllers\MyController::getMyCount() }}
モデルファイルに $appends プロパティをセットします
// SELECTされるデータセットに次の独自カラムを追加する
protected $appends = ['_editable_flag' , '_email_aisatsu' ];
任意のタイミングで appends に追加したいときにはメソッドを使用します。
return $user->append('is_admin')->toArray();
Laravelのモデル(Eloquent)の結果セット(Collection)に手動で任意のカラムを追加するには map() を使用します。
// コレクションのすべてのデータにurl = http://your.url/here を追加
$collection->map(function ($v) {
$v['url'] = 'http://your.url/here';
return $v;
});
// コレクションそれぞれに count=xxx (任意の値) を追加
$collection->map(function ($v) {
$v['count'] = <計算ロジック>;
return $v;
});
user_code カラムを隠して結果セットをjsonで返します
$collection->setHidden(['user_code'])->toJson(JSON_UNESCAPED_UNICODE)
getCollection() で コレクションを取り出してから行います
$paginator->getCollection()->map(function ($v) {
$v['count'] = <計算ロジック>;
return $v;
});
少し書式を変えたいときは Accessor /Mutator を使いましょう
モデルファイルに以下を記述
/**
* ● アクセサー : ->_star_mark で is_starred=1 の時に ☆ を表示する
*
*/
public function getStarMarkAttribute()
{
if ($this->attributes['is_starred'] == 1){
return '<div class="text-warning">★</div>';
}
}
呼び出し方
$model->star_mark
/**
* アクセサー : 「->dispatch_date_ja」 で 値「dispatch_date」が存在する時にフォーマットして表示する。存在しない場合は未発送を返す。
*/
public function getDispatchDateJaAttribute()
{
if ( $this->attributes['dispatch_date'] != null ){
$c = new \Carbon\Carbon($this->attributes['dispatch_date']);
return $c->format('m/d');
} else {
return '<span class="text-danger">未発送</span>';
}
}
呼び出し方
$model->dispatch_date_ja
composer require doctrine/dbal
add_columns_articles_table は任意の命名でOKですが「作業内容_テーブル名_table」としておくとテーブル作成時のファイルと命名が揃います
php artisan make:migration add_columns_articles_table --table=articles
例:「articles」テーブルに以下のカラムを追加します
・「status_id」カラムの後ろにint型の「recruit_flg」を追加します
・「recruit_flg」カラムの後ろにint型の「recruit_date」を追加します
public function up()
{
Schema::table('articles', function (Blueprint $table) {
$table->integer('recruit_flg')->default(0)->after('status_id'); // この行を追加
$table->dateTime('recruit_date')->nullable()->after('recruit_flg'); // この行を追加
});
}
注意:SQLiteでは任意の位置にカラム追加が出来ないようです
回避策 : https://goo.gl/a2atCx
public function down()
{
Schema::table('articles', function (Blueprint $table) {
$table->dropColumn(['recruit_date','recruit_flg']);
});
}
php artisan migrate
php artisan migrate:rollback
以上で、既存のデータベースのデータを削除することなく、カラムを追加できます。
LaravelでEloquentを使ってリレーションを設定し、リレーション先のテーブルを取得する方法です。
次のような2つのテーブルがあるとします
・「チーム」(teams)
・「ユーザー」(users)
このようにチームの中に複数のユーザーが所属するとします
─── マイチーム
├── 鈴木 一郎
├── 山田 太郎
├── 中村 二郎
モデル /app/Team.php
/**
* 1対多リレーション
*
* @return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function users() // 複数形(users)にする
{
// 「is_deleted = 0」のデータを「idの大きい順」で取得する
return $this->hasMany('App\User')->where('is_deleted', 0)->orderBy('id', 'DESC');
}
(取得条件やソート順を指定することができます。)
モデル /app/User.php
public function team() // 単数形(team)にする
{
return $this->belongsTo('App\Team');
}
use App\Team;
$all_teams = Team::with('users')->get();
dd( $all_teams->toArray() );
(実は with() メソッドを指定しなくても、Bladeテンプレートの中で リレーションオブジェクトを呼び出そうとすると自動取得されます。 ただ、自動取得が100回あると100回SQLクエリが投げられるので非効率です。with()メソッドだと in句 で一撃で取得してきます。)
方法1: with() を使ったやり方
$user = User::with('team')->find( Auth::user()->id );
dd( $user->toArray() );
実行されるSQL文
select * from `users`";
select * from `teams` where `teams`.`id` in (?); // ? は プレースホルダ
方法2: LEFT JOIN を使ったやり方
$user = User::leftJoin('teams','teams.id','=','users.team_id')->find( Auth::user()->id );
Mydump::dump( $user->toArray() );
実行されるSQL文
select * from `users` left join `teams` on `teams`.`id` = `users`.`team_id` where `users`.`id` = ? limit 1
$all_users = DB::table('users')
->leftJoin('teams','teams.id','=','users.team_id')
->get();
Mydump::dump( $all_users );
その他リレーションの参考: https://laravel-news.com/eloquent-tips-tricks