array appends php orm laravel eloquent

php - appends - laravel model join



¿Agregar un atributo personalizado a un modelo de Laravel/Eloquent en carga? (7)

Me gustaría poder agregar un atributo / propiedad personalizado a un modelo de Laravel / Eloquent cuando se carga, de forma similar a cómo se podría lograr con el RedBean''s $model->open() RedBean''s .

Por ejemplo, en este momento, en mi controlador tengo:

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

Sería bueno poder omitir el bucle y tener el atributo ''disponible'' ya configurado y poblado.

He intentado utilizar algunos de los eventos del modelo descritos en la documentación para adjuntar esta propiedad cuando se carga el objeto, pero sin éxito hasta el momento.

Notas:

  • ''disponible'' no es un campo en la tabla subyacente.
  • $sessions se devuelve como un objeto JSON como parte de una API y, por lo tanto, llamar a algo como $session->available() en una plantilla no es una opción

El problema está causado por el hecho de que el método toArray() del Model ignora cualquier acceso que no se relacione directamente con una columna en la tabla subyacente.

Como Taylor Otwell mencionó here , "Esto es intencional y por motivos de rendimiento". Sin embargo, hay una manera fácil de lograr esto:

class EventSession extends Eloquent { protected $table = ''sessions''; protected $appends = array(''availability''); public function getAvailabilityAttribute() { return $this->calculateAvailability(); } }

Cualquier atributo enumerado en la propiedad $ adjuntos se incluirá automáticamente en la matriz o el formulario JSON del modelo, siempre que haya agregado el descriptor de acceso adecuado.

Respuesta anterior (para versiones de Laravel <4.08):

La mejor solución que he encontrado es anular el método toArray() y explicity establecer el atributo:

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

o, si tiene muchos accesadores personalizados, recorra todos ellos y aplíquelos:

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


En mi modelo de suscripción, necesito saber si la suscripción está pausada o no. así es como lo hice en public function getIsPausedAttribute() { $isPaused = false; if (!$this->is_active) { $isPaused = true; } } public function getIsPausedAttribute() { $isPaused = false; if (!$this->is_active) { $isPaused = true; } }

luego, en la plantilla de vista, puedo usar $subscription->is_paused para obtener el resultado.

El getIsPausedAttribute es el formato para establecer un atributo personalizado,

y usa is_paused para obtener o usar el atributo en su vista.


Lo último en la página Laravel Eloquent doc es:

protected $appends = array(''is_admin'');

Eso se puede usar automáticamente para agregar nuevos accesos al modelo sin ningún trabajo adicional, como la modificación de métodos como ::toArray() .

Simplemente cree el getFooBarAttribute(...) y agregue el foo_bar a la matriz $appends foo_bar .


Si cambia el nombre de su método getAvailability() a getAvailableAttribute() su método se convierte en un acceso y podrá leerlo usando ->available directamente en su modelo.

Documentos: https://laravel.com/docs/5.4/eloquent-mutators#accessors-and-mutators

EDITAR: como su atributo es "virtual", no está incluido por defecto en la representación JSON de su objeto.

Pero encontré esto: ¿ Los accesadores de modelo personalizados no se procesan cuando se llama a> toJson ()?

Para forzar que su atributo sea devuelto en la matriz, agréguelo como una clave para la matriz $ attributes.

class User extends Eloquent { protected $attributes = array( ''ZipCode'' => '''', ); public function getZipCodeAttribute() { return .... } }

No lo probé, pero debería ser bastante trivial para que pruebes en tu configuración actual.


Tenía algo simular: tengo una imagen de atributo en mi modelo, esta contiene la ubicación del archivo en la carpeta de Almacenamiento. La imagen debe devolverse codificada en 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); }


en mi caso, crear una columna vacía y configurar su acceso funcionaba bien. mi acceso rellena la edad del usuario de la columna dob. La función toArray () también funcionó.

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


puede usar la función setAttribute en Model para agregar un atributo personalizado