モデルに処理を書くことで、view の記述は以下のように劇的に簡素になります。
View bladeでの記述
blade
1@foreach ($members as $member)
2 <img src="{{ asset($member->icon) }}">
3@endforeach
DB定義
bash
1php artisan make:migration create_members_table
多少、プロパティの設定値など変更してある
- 男性、女性、の設定値: 0 はPHPでは扱いにくいので、男性:1, 女性:2 とした
- カラムから、age は取り除いた。birthday を持てば、誕生日のインクリメントの仕組みは不要だから。
php
1<?php
3use Illuminate\Database\Migrations\Migration;
4use Illuminate\Database\Schema\Blueprint;
5use Illuminate\Support\Facades\Schema;
7class CreateMembersTable extends Migration
8{
9 1213
14 public function up()
15 {
16 Schema::create('members', function (Blueprint $table) {
17 $table->bigIncrements('id');
18 $table->string('name')->comment('名前');
19 $table->date('birthday')->comment('生年月日');
20 $table->unsignedTinyInteger('sex')->nullable()->comment('性別:男性:1,女性:2');
21 $table->unsignedTinyInteger('status')->default(1)->comment('ステータス:有効:1,無効:0');
22 $table->timestamps();
23 $table->softDeletes();
24 });
25 }
27 3031
32 public function down()
33 {
34 Schema::dropIfExists('members');
35 }
36}
Factory
bash
1php artisan make:factory MemberFactory --model=Member
php
1<?php
2
3
4
5use App\Member;
6use Faker\Generator as Faker;
7
8$factory->define(Member::class, function (Faker $faker) {
9 return [
10 'name' => $faker->name,
11 'birthday' => $faker->date('Y-m-d', '-10 years'),
12 'sex' => $faker->randomElement([1, 2]),
13 'status' => $faker->randomElement([0, 1]),
14 ];
15});
Model(必須)
bash
1php artisan make:model Member
- dates プロパティに birthday を指定しておけば、Carbon に自動で変換されるので、age の取得が楽
- get...Attribute() を使いこなせば、blade の記述が劇的に簡素になる
php
1<?php
2
3namespace App;
4
5use Carbon\Carbon;
6use Illuminate\Database\Eloquent\Model;
7use Illuminate\Database\Eloquent\SoftDeletes;
8use Mockery\Exception;
9
1011 * Class Member
1213 *
14151617181920
21class Member extends Model
22{
23 use SoftDeletes;
24
25 26 * 有効
27
28 const ACTIVE = 1;
29
30 31 * 無効
32
33 const INACTIVE = 0;
34
35 36 * 男性
37
38 const MALE = 1;
39
40 41 * 女性
42
43 const FEMALE = 2;
44
45 protected $fillable = [
46 'name',
47 'birthday',
48 'sex',
49 'status',
50 ];
51
52 protected $dates = [
53 'birthday'
54 ];
55
56 57 * 有効かの判定
5859
60 public function isActive(): bool
61 {
62 return $this->status === self::ACTIVE;
63 }
64
65 66 * 無効かの判定
6768
69 public function isInactive(): bool
70 {
71 return $this->status === self::INACTIVE;
72 }
73
74 75 * 男性かの判定
7677
78 public function isMale(): bool
79 {
80 return $this->sex === self::MALE;
81 }
82
83 84 * 女性かの判定
8586
87 public function isFemale(): bool
88 {
89 return $this->sex === self::FEMALE;
90 }
91
92 93 * 成人かどうか
9495
96 public function isAdult(): bool
97 {
98 return $this->age >= 20;
99 }
100
101 102 * 年齢を取得
103104
105 public function getAgeAttribute(): int
106 {
107 return $this->birthday->age;
108 }
109
110 111 * アイコンのファイル名を取得
112113114
115 public function getIconAttribute(): string
116 {
117 switch ($this->sex) {
118 case self::MALE:
119 $path = 'img/male';
120 break;
121 case self::FEMALE:
122 $path = 'img/female';
123 break;
124 default:
125 // DB定義上、NULL許可なので
126 throw new Exception('性別が指定されていません。');
127 }
128
129 if ($this->isAdult()) {
130 $path .= '/adult-';
131 } else {
132 $path .= '/young-';
133 }
134
135 if ($this->isActive()) {
136 $path .= 'active.svg';
137 } else {
138 $path .= 'inactive.svg';
139 }
140
141 return $path;
142 }
143}
確認のための不完全なTEST
bash
1php artisan make:test MemberTest
php
1<?php
2
3namespace Tests\Feature;
4
5use App\Member;
6use Tests\TestCase;
7
8class MemberTest extends TestCase
9{
10 private $members;
11
12 public function setUp(): void
13 {
14 parent::setUp();
15
16 $this->members = factory(Member::class, 100)->make();
17 }
18
19 public function testIcon()
20 {
21 $this->members->each(function (Member $member) {
22 dump($member->icon);
23 });
24 }
25}