2017-06-22 86 views
-1

因此,我有一個Page模型,它擴展了EloquentModel類。我想重寫構造函數,我需要一些額外的邏輯。這是我目前有:Laravel雄辯 - 覆蓋模型的構造函數來更改屬性

class Page extends Model 
{ 

    public function __construct(array $attributes = []) 
    { 

     parent::__construct($attributes); 
     $this->main_image = null; 
    } 

} 

但這似乎並沒有給main_image保存到$this->attributes財產當我打電話Page::find(1);

我相信這是因爲Page::find最後調用Model::newFromBuilder,它看起來像這樣:

public function newFromBuilder($attributes = [], $connection = null) 
{ 
    $model = $this->newInstance([], true); 

    $model->setRawAttributes((array) $attributes, true); 

    $model->setConnection($connection ?: $this->getConnectionName()); 

    return $model; 
} 

因此,大家可以看到它首先創建實例,然後設置屬性,這意味着,任何在構造函數中設置被忽略。

是否有任何解決方法可以重寫構造函數(或類似的方法)來更改每個檢索/創建的模型實例的屬性?很明顯,我可以覆蓋newFromBuilder,newInstance,__construct和類似的方法,但這看起來很不方便,不可維護。

謝謝!

+0

所以,基本上你想要重寫一個參數,每當你創建一個新的元素?您應該使用模型事件https://laravel.com/docs/5.4/eloquent#events - 特別是查看「創建/創建」。 – Gacek

+0

覆蓋只是一個例子,可能有多個參數覆蓋,他們會被包裹在if語句等。我會檢查出事件,如果我可以將它們應用於所有類而無需爲每個模型編寫Observer類得到。謝謝! – Giedrius

+0

你的模型還沒有'main_image'字段嗎?在模型中設置它的最終目標是什麼?如果所有頁面都有一個'main_image',可能會有另外一種解決這個問題的方法,可能會形成一個關係,以便你可以執行'$ page-> mainImage-> get()' – Mikey

回答

0

如果你需要的是能夠自動修改模型的屬性檢索或設置時,則使用Laravel Eloquent's Accesors and Mutators

定義一個訪問

要定義的訪問,上創建getFooAttribute方法你模型,其中Foo是您希望訪問的列的「完美」名稱。在這個例子中,我們將爲first_name屬性定義一個訪問器。訪問者將自動雄辯試圖檢索FIRST_NAME屬性的值時,被稱爲:

<?php 

namespace App; 

use Illuminate\Database\Eloquent\Model; 

class User extends Model 
{ 
    /** 
    * Get the user's first name. 
    * 
    * @param string $value 
    * @return string 
    */ 
    public function getFirstNameAttribute($value) 
    { 
     return ucfirst($value); 
    } 
} 

正如你所看到的,列的原始值傳遞給存取,讓你操作並返回值。要訪問存取的值,你可以簡單地訪問模型實例的FIRST_NAME屬性:

$user = App\User::find(1); 

$firstName = $user->first_name; 

定義賦值函數

要定義一個突變,在你的模型,其中富定義setFooAttribute方法是您希望訪問的列的「完美」名稱。因此,我們再爲first_name屬性定義一個增變器。這種突變會,當我們嘗試設置模型上的FIRST_NAME屬性的值被自動調用:

<?php 

namespace App; 

use Illuminate\Database\Eloquent\Model; 

class User extends Model 
{ 
    /** 
    * Set the user's first name. 
    * 
    * @param string $value 
    * @return void 
    */ 
    public function setFirstNameAttribute($value) 
    { 
     $this->attributes['first_name'] = strtolower($value); 
    } 
} 

的突變將收到被該屬性的設定值,讓您操作值和設定Eloquent模型的內部$ attributes屬性上的操縱值。因此,舉例來說,如果我們試圖將FIRST_NAME屬性設置爲莎莉:

$user = App\User::find(1); 

$user->first_name = 'Sally'; 

在這個例子中,setFirstNameAttribute功能與價值薩利被調用。然後,mutator會將strtolower函數應用於名稱,並將其結果值設置到內部$ attributes數組中。