Laravel 学習記録 #007 アクセサ、ミューテータを学ぶ
Laravelのアクセサ、ミューテータについて学習したものをまとめてます。
アクセサ、ミューテータとは?
Eloquentモデルでデータを加工する機能
アクセサは、データベースの値を取得するときに値を加工できるメソッド(テーブルのフィールドに対応するプロパティを上書きして取得できる機能)
ミューテータはデータベースに値を設定する前に、値を変更または加工するためのメソッド(値を設定する処理を上書きして設定する機能)
アクセサの使い方
アクセサを使用するにはモデルに
get<任意の命名>Attribute
の名前でメソッドを作成します。
public function getXXAttribute(){
// 処理
return 値;
}
任意の命名の箇所を既存のプロパティ名とすることで、取得結果を上書き
既存のプロパティにはない命名とすることで、その名前で使えるようなります。
やってみる
マイグレーションファイルを下記のようにして「チームテーブル」を作成して確認してみます。
public function up(): void
{
Schema::create('teams', function (Blueprint $table) {
$table->id();
$table->string('team_name');
$table->timestamps();
});
}
任意の命名のパターン
アクセサで、取得するチーム名に対して「アクセサで付与された説明」という文字列を追加してみます。
getTeamNameAddDescriptionAttributeメソッドを作成
処理としては取得のteam_nameに文字列を追加しただけです。
class Team extends Model
{
use HasFactory;
// アクセサ
public function getTeamNameAddDescriptionAttribute(){
return 'アクセサで付与された説明:' . $this->team_name;
}
}
コントローラーで確認してみます。
アクセサで定義したやつを呼び出す際には、キャメルケースの命名をスネークケースに変換することで、他のプロパティ同様呼び出せます。
(定義がgetAaaBbbAttribute()の場合は、aaa_bbbとする)
Team::first()->teamName_add_description
結果確認
class ModelTestController extends Controller
{
public function index() {
dd(Team::first()->teamName_add_description);
}
}
結果
"アクセサで付与された説明:チームA"
既存の命名のパターン
既存のプロパティを変更するには
get<プロパティ名>Attribute()
として、プロパティに引数を渡す必要があります。
team_nameプロパティを変更してみます。
// アクセサ(既存のプロパティを変更)
public function getTeamNameAttribute($value) {
return "アクセサで既存のプロパティを変更:" . $value;
}
では、コントローラーで確認してみます。
既存のプロパティを変更しているので、通常の呼び方でOKです。
class ModelTestController extends Controller
{
public function index() {
// アクセサでteam_nameに説明文を追加
// 呼び出す際にはgetAaaBbbAttribute()の「AaaBbb」をスネークケースに変換
// dd(Team::first()->teamName_add_description);
// 既存のプロパティを変更
dd(Team::first()->team_name);
}
}
結果
"アクセサで既存のプロパティを変更:チームA"
このように、取得結果を加工することが可能です。
データベースで0,1などの値を管理し、表示には文字列のラベルを表示したい。なんてときは特に活躍しそうですよね。
ミューテータの使い方
ミューテータを使用するにはモデルに
set<任意の命名>Attribute
の名前でメソッドを作成し引数(渡された値)をセットします。
public function setXXAttribute(引数){
// 処理
return 値;
}
任意の命名の箇所を既存のプロパティ名とすることで、値を上書きし
既存のプロパティにはない命名とすることで、その名前で使えるようなります。
やってみる
アクセサ同様「チームテーブル」で試します。
任意の命名のパターン
ミューテータで、登録するチーム名に対して「ミューテータで付与された説明」という文字列を追加してみます。
setTeamNameAddDescriptionAttributeメソッドを作成
処理としては登録のteam_nameに文字列を追加しただけです。
class Team extends Model
{
// アクセサ
public function setTeamNameAddDescriptionAttribute($value) {
return $this->attributes['team_name'] = 'ミューテータで付与された説明:' . $value;
}
}
登録処理で確認してみます。
アクセサで定義したやつを使う際には、アクセサ同様キャメルケースの命名をスネークケースに変換してよびます。
team_name_add_description
結果確認
class ModelTestController extends Controller
{
public function store() {
// ミューテーターで登録時に加工
$team = new Team();
$team->team_name_add_description = "Aチーム";
$team->save();
dd($team);
}
}
結果
#attributes: array:4 [▼
"team_name" => "ミューテーターで付与された説明:Aチーム"
"updated_at" => "2023-10-07 01:17:03"
"created_at" => "2023-10-07 01:17:03"
"id" => 4
]
登録後のteam_nameの値がミューテータで設定した値になっていることがわかります。
既存の命名のパターン
既存のプロパティを変更するには
set<プロパティ名>Attribute()
として、プロパティに引数を渡す必要があります。
team_nameプロパティを変更してみます。
// ミューテータ(既存のプロパティを変更)
public function setTeamNameAttribute($value) {
return $this->attributes['team_name'] = 'ミューテータで既存プロパティを変更:' . $value;
}
では、コントローラーで確認してみます。
既存のプロパティを変更しているので、通常のセットでOKです。
class ModelTestController extends Controller
{
public function store() {
// 既存のプロパティを変更
$team = new Team();
$team->team_name = "Aチーム";
$team->save();
}
}
結果
#attributes: array:4 [▼
"team_name" => "ミューテーターで既存プロパティを変更:Aチーム"
"updated_at" => "2023-10-07 01:20:38"
"created_at" => "2023-10-07 01:20:38"
"id" => 6
]
このように、登録する値を加工することが可能です。
パスワード登録でハッシュ化したい時、なんかに使えそうですね。
アクセサ、ミューテータ、カスタムコレクションはLaravelのModelを使い倒すために抑えておきたい機能ですね。
ちなみに取得時にはアクセサ→カスタムコレクションの順で機能しているようでした。
この記事が気に入ったらサポートをしてみませんか?