簡體   English   中英

在加載時向 Laravel/Eloquent 模型添加自定義屬性?

[英]Add a custom attribute to a Laravel / Eloquent model on load?

我希望能夠在加載時向 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()的內容

該問題是由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);    
    }

}

Laravel Eloquent 文檔頁面上的最后一件事是:

protected $appends = array('is_admin');

這可以自動用於向模型添加新的訪問器,而無需任何額外的工作,例如修改::toArray()類的方法。

只需創建getFooBarAttribute(...)訪問器並將foo_bar添加到$appends getFooBarAttribute(...)數組。

如果您將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 ....
    }
}

我沒有測試它,但對於您在當前設置中嘗試應該非常簡單。

我有一些類似的東西:我的模型中有一個屬性圖片,它包含文件在 Storage 文件夾中的位置。 圖像必須返回 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);
}

第 1 步:在$appends定義屬性
第 2 步:為該屬性定義訪問器。
例子:

<?php
...

class Movie extends Model{

    protected $appends = ['cover'];

    //define accessor
    public function getCoverAttribute()
    {
        return json_decode($this->InJson)->cover;
    }

您可以在模型中使用setAttribute函數添加自定義屬性

假設您的用戶表中有 2 列名為 first_name 和 last_name,並且您想要檢索全名。 您可以使用以下代碼實現:

class User extends Eloquent {


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

現在你可以得到全名:

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

在我的訂閱模型中,我需要知道訂閱是否暫停。 這是我如何做到的

public function getIsPausedAttribute() {
    $isPaused = false;
    if (!$this->is_active) {
        $isPaused = true;
    }
}

然后在視圖模板中,我可以使用$subscription->is_paused來獲得結果。

getIsPausedAttribute是設置自定義屬性的格式,

並使用is_paused在您的視圖中獲取或使用該屬性。

就我而言,創建一個空列並設置其訪問器工作正常。 我的訪問器從 dob 列填充用戶的年齡。 toArray() 函數也有效。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM