web-dev-qa-db-ja.com

ロード時にLaravel / Eloquentモデルにカスタム属性を追加しますか?

ロード時にLaravel/Eloquentモデルにカスタム属性/プロパティを追加できるようにしたいと思います。これは RedBeanの$model->open()メソッドで実現できるのと同じように。

たとえば、現時点では、私のコントローラには、次のものがあります。

public function index()
{
    $sessions = EventSession::all();
    foreach ($sessions as $i => $session) {
        $sessions[$i]->available = $session->getAvailability();
    }
    return $sessions;
}

ループを省略して 'available'属性をすでに設定してデータを追加できるようにするとよいでしょう。

オブジェクトのロード時にこのプロパティを添付するために、ドキュメントに記載されているモデルイベントのいくつかを使用してみましたが、これまでのところ成功していません。

注:

  • 'available'は基礎となるテーブル内のフィールドではありません。
  • $sessionsはAPIの一部としてJSONオブジェクトとして返されているため、テンプレートで$session->available()のようなものを呼び出すことはできません。
178
coatesap

この問題は、ModeltoArray()メソッドが、基礎となるテーブルの列に直接関連しないアクセサを無視するという事実によって引き起こされます。

Taylor Otwellがここ で述べたように 、「これは意図的なものであり、パフォーマンス上の理由からです。」しかし、これを実現する簡単な方法があります。

class EventSession extends Eloquent {

    protected $table = 'sessions';
    protected $appends = array('availability');

    public function getAvailabilityAttribute()
    {
        return $this->calculateAvailability();  
    }
}

適切なアクセサを追加していれば、$ appendsプロパティにリストされているすべての属性が自動的にモデルの配列またはJSON形式に含まれます。

古い答え(Laravelバージョン<4.08用):

私が見つけた最良の解決策はtoArray()メソッドをオーバーライドして明示的に属性を設定することです:

class Book extends Eloquent {

    protected $table = 'books';

    public function toArray()
    {
        $array = parent::toArray();
        $array['upper'] = $this->upper;
        return $array;
    }

    public function getUpperAttribute()
    {
        return strtoupper($this->title);    
    }

}

あるいは、カスタムアクセサがたくさんある場合は、それらをすべてループして適用します。

class Book extends Eloquent {

    protected $table = 'books';

    public function toArray()
    {
        $array = parent::toArray();
        foreach ($this->getMutatedAttributes() as $key)
        {
            if ( ! array_key_exists($key, $array)) {
                $array[$key] = $this->{$key};   
            }
        }
        return $array;
    }

    public function getUpperAttribute()
    {
        return strtoupper($this->title);    
    }

}
283
coatesap

Laravel Eloquentドキュメントページの最後のもの は次のとおりです。

protected $appends = array('is_admin');

::toArray()のようなメソッドを修正するような追加の作業なしに、自動的にそれを使って新しいアクセサをモデルに追加することができます。

getFooBarAttribute(...)アクセサを作成し、foo_bar$appends配列に追加するだけです。

113
trm42

getAvailability()メソッドの名前をgetAvailableAttribute()に変更すると、そのメソッドはアクセサになり、モデル上で->availableを使用して読み取ることができます。

ドキュメント: https://laravel.com/docs/5.4/eloquent-mutators#accessors-and-mutators

編集:あなたの属性は "仮想"であるため、それはあなたのオブジェクトのJSON表現にデフォルトで含まれていません。

しかし、私はこれを見つけました: - > toJson()が呼ばれたときにカスタムモデルアクセサが処理されませんでした?

属性を配列に返させるには、それを$ attributes配列のキーとして追加します。

class User extends Eloquent {
    protected $attributes = array(
        'ZipCode' => '',
    );

    public function getZipCodeAttribute()
    {
        return ....
    }
}

私はそれをテストしませんでした、しかしあなたがあなたの現在の設定で試してみることはかなり簡単なはずです。

36

私は何か同じようなものを持っていました:私は自分のモデルの中に属性画像があります、これはStorageフォルダの中のファイルの場所を含みます。画像はbase64エンコードで返される必要があります

//Add extra attribute
protected $attributes = ['pictureData'];

//Make it available in the json response
protected $appends = ['pictureData'];

//implement the attribute
public function getPictureDataAttribute()
{
    $file = Storage::get($this->picture);
    $type = Storage::mimeType($this->picture);
    return "data:" . $type . ";base64," . base64_encode($file);
}
13
Patrique

modelでsetAttribute関数を使ってカスタム属性を追加することができます

13
jianfeng

Usersテーブルにfirst_nameとlast_nameという2つのカラムがあり、フルネームを取得したいとしましょう。次のコードで達成できます。

class User extends Eloquent {


    public function getFullNameAttribute()
    {
        return $this->first_name.' '.$this->last_name;
    }
}

今、あなたはフルネームを得ることができます:

$user = User::find(1);
$user->full_name;
5
ShuBham GuPta

私の場合は、空の列を作成してそのアクセサを設定するとうまくいきました。私のアクセサはdobカラムからユーザの年齢を埋めます。 toArray()関数も機能しました。

public function getAgeAttribute()
{
  return Carbon::createFromFormat('Y-m-d', $this->attributes['dateofbirth'])->age;
}
1
Hanif Rifa'i

私の購読モデルでは、購読が一時停止されているかどうかを知る必要があります。これが私のやり方ですpublic function getIsPausedAttribute() { $isPaused = false; if (!$this->is_active) { $isPaused = true; } }

ビューテンプレートでは、結果を取得するために$subscription->is_pausedを使用できます。

getIsPausedAttributeはカスタム属性を設定するためのフォーマットです。

ビュー内の属性を取得または使用するためにis_pausedを使用します。

0
li bing zhao