Dodać własny atrybut do modelu Laravel / Eloquent przy ładowaniu?
Chciałbym móc dodać niestandardowy atrybut / właściwość do modelu Laravel / Eloquent po załadowaniu, podobny do tego, jak można to osiągnąć z RedBean ' s $model->open()
Metoda.
Na przykład w tej chwili w moim kontrolerze mam:
public function index()
{
$sessions = EventSession::all();
foreach ($sessions as $i => $session) {
$sessions[$i]->available = $session->getAvailability();
}
return $sessions;
}
Byłoby miło móc pominąć pętlę i mieć atrybut' available ' już ustawiony i wypełniony.
Próbowałem użyć niektórych zdarzeń modelu opisanych w dokumentacji, aby załączyć to właściwość, gdy obiekt ładuje się, ale do tej pory bez powodzenia.
uwagi:
- "dostępny" nie jest polem w tabeli bazowej.
-
$sessions
jest zwracany jako obiekt JSON jako część API, a zatem wywołanie czegoś takiego jak$session->available()
w szablonie nie jest opcją
9 answers
Problem jest spowodowany faktem, że metoda Model
S toArray()
ignoruje wszelkie Accesory, które nie odnoszą się bezpośrednio do kolumny w tabeli bazowej.
Jak wspomniał Taylor Otwell tutaj, "jest to celowe i ze względów wydajnościowych."Jednak jest łatwy sposób, aby to osiągnąć:
class EventSession extends Eloquent {
protected $table = 'sessions';
protected $appends = array('availability');
public function getAvailabilityAttribute()
{
return $this->calculateAvailability();
}
}
Wszelkie atrybuty wymienione we właściwości $ appends zostaną automatycznie dołączone do tablicy lub postaci JSON modelu, pod warunkiem, że dodałeś odpowiednie / align = "left" /
Stara odpowiedź (dla wersji Laravel
Najlepszym rozwiązaniem, jakie znalazłem, jest nadpisanie metody toArray()
i albo explicity ustaw atrybut:
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);
}
}
Jeśli masz wiele niestandardowych akcesoriów, przejrzyj je wszystkie i zastosuj:]}
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);
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-03 13:59:45
Ostatnia rzecz na stronie Laravel Eloquent doc to:
protected $appends = array('is_admin');
, które mogą być używane automatycznie do dodawania nowych accesorów do modelu bez żadnych dodatkowych prac, takich jak modyfikowanie metod, takich jak ::toArray()
.
Po prostu utwórz getFooBarAttribute(...)
accessor i dodaj foo_bar
do $appends
tablicy.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-08 06:01:30
Jeśli zmienisz nazwę swojej metody getAvailability()
na getAvailableAttribute()
twoja metoda stanie się accessorem i będziesz mógł ją odczytać używając ->available
bezpośrednio na twoim modelu.
Docs: https://laravel.com/docs/5.4/eloquent-mutators#accessors-and-mutators
EDIT: ponieważ twój atrybut jest "wirtualny", nie jest on domyślnie uwzględniany w reprezentacji JSON Twojego obiektu.
Ale znalazłem to: Custom model accessors Nie przetwarzane, gdy ->tojson() wywołane?
In aby wymusić zwrócenie atrybutu w tablicy, dodaj go jako klucz do tablicy $ attributes.
class User extends Eloquent {
protected $attributes = array(
'ZipCode' => '',
);
public function getZipCodeAttribute()
{
return ....
}
}
Nie testowałem go, ale powinno być dość trywialne dla ciebie, aby spróbować w obecnej konfiguracji.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-16 20:21:24
Miałem coś symulowanego: Mam obraz atrybutu w moim modelu, który zawiera lokalizację pliku w folderze przechowywania. Obraz musi być zwrócony Base64 zakodowany
//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);
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-09-05 11:13:40
Możesz użyć funkcji setAttribute
w modelu, aby dodać własny atrybut
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-10-28 07:59:08
Krok 1: Zdefiniuj atrybuty w $appends
Krok 2: Zdefiniuj accessor dla tych atrybutów.
Przykład:
<?php
...
class Movie extends Model{
protected $appends = ['cover'];
//define accessor
public function getCoverAttribute()
{
return json_decode($this->InJson)->cover;
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-03-27 03:35:16
Powiedzmy, że masz 2 kolumny o nazwach first_name i last_name w tabeli users i chcesz odzyskać pełną nazwę. możesz osiągnąć za pomocą następującego kodu:
class User extends Eloquent {
public function getFullNameAttribute()
{
return $this->first_name.' '.$this->last_name;
}
}
Teraz możesz uzyskać pełną nazwę jako:
$user = User::find(1);
$user->full_name;
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-01-23 12:26:25
W moim modelu subskrypcji, muszę wiedzieć, że subskrypcja jest wstrzymana lub nie. oto jak to zrobiłem
public function getIsPausedAttribute() {
$isPaused = false;
if (!$this->is_active) {
$isPaused = true;
}
}
Wtedy w szablonie widoku mogę użyć
$subscription->is_paused
Aby uzyskać wynik.
{[2] } jest formatem do ustawiania niestandardowego atrybutu,
I używa is_paused
, aby uzyskać lub użyć atrybutu w widoku.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-09-21 23:46:23
W moim przypadku tworzenie pustej kolumny i ustawianie jej accesora działało dobrze. mój accessor wypełniający wiek użytkownika z kolumny dob. funkcja toArray() również działała.
public function getAgeAttribute()
{
return Carbon::createFromFormat('Y-m-d', $this->attributes['dateofbirth'])->age;
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-31 21:53:11