263

RedBean の メソッドで実現できる方法と同様に、ロード時にカスタム属性/プロパティを Laravel/Eloquent モデルに追加できるようにしたいと考えています$model->open()

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

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

ループを省略して、「使用可能」属性をすでに設定して入力できると便利です。

ドキュメントに記載されているモデル イベントのいくつかを使用して、オブジェクトの読み込み時にこのプロパティをアタッチしようとしましたが、今のところ成功していません。

ノート:

  • 「利用可能」は、基になるテーブルのフィールドではありません。
  • $sessionsAPIの一部としてJSONオブジェクトとして返されているため$session->available()、テンプレートのようなものを呼び出すことはできません
4

9 に答える 9

380

この問題は、ModeltoArray()メソッドが、基になるテーブルの列に直接関係しないアクセサーを無視するために発生します。

テイラー・オトウェルがここで述べたように、「これは意図的であり、パフォーマンス上の理由によるものです」。ただし、これを実現する簡単な方法があります。

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);    
    }

}
于 2013-06-22T11:51:10.047 に答える
30

モデルに属性画像があり、これにはストレージフォルダー内のファイルの場所が含まれています。画像はbase64でエンコードされたものを返す必要があります

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

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

//implement the attribute
public function getPictureDataAttribute()
{
    $file = Storage::get($this->picture);
    $type = Storage::mimeType($this->picture);
    return "data:" . $type . ";base64," . base64_encode($file);
}
于 2015-12-29T22:26:45.783 に答える
19

setAttributeモデルの関数を使用してカスタム属性を追加できます

于 2014-10-28T07:59:08.910 に答える
2

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

public function getAgeAttribute()
{
  return Carbon::createFromFormat('Y-m-d', $this->attributes['dateofbirth'])->age;
}
于 2016-03-31T19:19:06.060 に答える