DBから取得した値を自動で加工してくれる便利な機能のアクセサですが、時としてアクセサを無視してDBから取得した素の値が欲しいケースがあります。そんな時に使える方法を3つ紹介します。
どういうケース?
例えば、公式ドキュメントの「アクセサの定義」には例として以下のコードが紹介されています。
<?php namespace App; use Illuminate\Database\Eloquent\Model; class User extends Model { /** * ユーザーのファーストネームを取得 * * @param string $value * @return string */ public function getFirstNameAttribute($value) { return ucfirst($value); } }
そして、定義したアクセサにより名前の出力は頭文字が大文字となります。
$user->first_name; // DBに保存されている素の値は"hikaru" >> "Hikaru"
今回はこのようにアクセサを定義したものの、例外的にDBに保存されている素の値である”hikaru”が欲しくなった、という時に使える方法の解説です。
1. $attributes
まず1つ目に、アクセサを定義したクラス内で使える方法です。DBから取得した素の値は$attributes
というprotectedプロパティに格納されているため、Modelクラス内からアクセス可能です。例えば前項のUserクラスにgetPlainFirstName()
を追加してみましょう。
<?php namespace App; use Illuminate\Database\Eloquent\Model; class User extends Model { /** * ユーザーのファーストネームを取得 * * @param string $value * @return string */ public function getFirstNameAttribute($value) { return ucfirst($value); } public function getPlainFirstName() { return $this->attributes['first_name']; } }
メソッドを呼び出すと素の値が取得できます。
$user->getPlainFirstName(); >> "hikaru"
因みに、$attributes
はvendor/laravel/framework/src/Illuminate/Database/Eloquent/Concerns/HasAttributes.phpにて定義されています。
2. getRawOriginal()
続いて、Userクラス外から素の値にアクセスする方法として、getRawOriginal()
が使えます。
$user->getRawOriginal('first_name'); >> "hikaru"
1点注意が必要なのは、このメソッドは$original
というプロパティから値を取得しています。$original
にはDBから取得した時点の値を保持する配列が格納されており、getDirty()
などで変更が加わった項目を判別する際などに使われています。
つまり、DBから取得した後に変更した値は取得できません。
$user->first_name = 'kenji'; // 名前を"hikaru"から"kenji"に変更 $user->getRawOriginal('first_name'); // $originalから値を取得するので"hikaru"のまま >> "hikaru"
こちらのメソッドもHasAttributes.phpに定義されているのでソースを確認してみてください。
3. getAttributes()
最後に紹介するgetAttributes()
は$attributes
を返すメソッドです。Userクラス外からアクセスでき、DBから取得した後に値を変更しても変更後の値が取得できます。getRawOriginal()
とは異なり引数でキーを指定できない($attributes
そのものを返す)為、取得後に項目を指定する必要があります。
$user->getAttributes()['first_name']; >> "hikaru" $user->first_name = "kenji"; $user->getAttributes()['first_name']; // 変更後の値が取得できる >> "kenji"
まとめ
以上、アクセサを無視してDBから取得した素の値を取得する方法3つの紹介でした。
紹介しておいてなのですが、アクセサを無視しなければならない箇所がいくつもある場合は今回紹介した方法で置き換えるよりも、本当にそのアクセサが必要なのか?見直す方が良いかと思います。