php - tables - Adicionar um atributo personalizado a um modelo do Laravel/Eloquent no carregamento?




relationship tables laravel (6)

A última coisa na página de documentação do Laravel Eloquent é:

protected $appends = array('is_admin');

Isso pode ser usado automaticamente para adicionar novos acessadores ao modelo sem qualquer trabalho adicional, como modificar métodos como ::toArray() .

Apenas crie o getFooBarAttribute(...) e adicione o array foo_bar ao $appends .

Eu gostaria de poder adicionar um atributo / propriedade personalizado a um modelo do Laravel / Eloquent quando ele é carregado, semelhante a como isso pode ser alcançado com o RedBean's $model->open() RedBean's $model->open() RedBean's .

Por exemplo, no momento, no meu controlador eu tenho:

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

Seria bom poder omitir o loop e ter o atributo 'disponível' já definido e preenchido.

Eu tentei usar alguns dos eventos de modelo descritos na documentação para anexar essa propriedade quando o objeto é carregado, mas sem sucesso até agora.

Notas:

  • 'disponível' não é um campo na tabela subjacente.
  • $sessions está sendo retornado como um objeto JSON como parte de uma API e, portanto, chamar algo como $session->available() em um modelo não é uma opção

Digamos que você tenha duas colunas chamadas first_name e last_name na sua tabela de usuários e deseja recuperar o nome completo. você pode conseguir com o seguinte código:

class User extends Eloquent {


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

agora você pode obter o nome completo como:

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

No meu modelo de assinatura, preciso saber se a assinatura está pausada ou não. aqui está como eu fiz isso public function getIsPausedAttribute() { $isPaused = false; if (!$this->is_active) { $isPaused = true; } } public function getIsPausedAttribute() { $isPaused = false; if (!$this->is_active) { $isPaused = true; } }

então, no modelo de visualização, posso usar $subscription->is_paused para obter o resultado.

O getIsPausedAttribute é o formato para definir um atributo personalizado,

e usa is_paused para obter ou usar o atributo na sua visualização.


O problema é causado pelo fato de que o método toArray() do Model ignora quaisquer acessadores que não estejam diretamente relacionados a uma coluna na tabela subjacente.

Como Taylor Otwell mencionou here , "isso é intencional e por razões de desempenho". No entanto, existe uma maneira fácil de conseguir isso:

class EventSession extends Eloquent {

    protected $table = 'sessions';
    protected $appends = array('availability');

    public function getAvailabilityAttribute()
    {
        return $this->calculateAvailability();  
    }
}

Todos os atributos listados na propriedade $ appends serão incluídos automaticamente no array ou no formulário JSON do modelo, desde que você tenha adicionado o acessador apropriado.

Resposta antiga (para versões do Laravel <4.08):

A melhor solução que encontrei é sobrepor o método toArray() e definir explicitamente o 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);    
    }

}

ou, se você tiver muitos acessadores customizados, faça o loop de todos eles e aplique-os:

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

}

no meu caso, criar uma coluna vazia e configurar seu acessador funcionou bem. meu acessador preenchendo a idade do usuário da coluna dob. A função toArray () também funcionou.

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

você pode usar a função setAttribute em Model para adicionar um atributo personalizado