Is it mandatory to go through Mutator / Accessor?

1

I just faced a problem in Laravel 5.1 .

Imagine that I have the following:

Model

class User extends Model{

   # Mutator

   public function getNomeUpperAttribute(){
       return strtoupper($this->attributes['nome']);
   }

}

Controller

public function index(){

   $user = User::find(1);

   $user->nome_upper;

}

Return

  

NAME IN MAIL

But let's suppose I made a JOIN by Eloquent and do not select the name field of the Users table.

public function index(){

   $user = User::join('enderecos', 'enderecos.id_user', '=', 'users.id')
                 ->select('rua', 'bairro', 'numero', 'cep')
                 ->where('id_user', '=', 1)
                 ->first();

}

When this happens the page gives an error:

  

undefined index 'name';

This happens because it enters the role that I set in Model Users .

To make no mistake, I have to do a check like this:

public function getNomeUpperAttribute(){
    if(array_key_exists('nome', $this->attributes))
        return strtoupper($this->attributes['nome']);
    else
        return null;
}

But imagine that I have several Accessors to customize various fields. I would have to do this check at all.

The question is:

Is this really necessary? Is there no other way?

    
asked by anonymous 14.10.2016 / 16:24

1 answer

3

A small fix: This is not called Mutator , but rather Accessor .

Mutator is to define the attribute, Accessor is to access.

In some frameworks that have the same purpose as an Accessor , this is called Virtual Field .

Accessor's use is limited to cases where you need a specific formatting for a particular field in your table. There are possibilities to return other types of information, but generally you will want to use them to work with specific table data.

So, whenever you need to format a certain field in the result of a query, you will need it to be selected via select .

In your case, the Undefined Index error occurs because the field was not selected.

Answering your question: Yes, you would need to check every time, which I do not see is not a problem, since you only define a method once, but reuse it throughout your application.

Another detail: Instead of using $this->attributes['valor'] , you can use $this->valor directly.

public function getNomeUpperAttribute(){
   return strtoupper($this->nome);
}

The only remark I make in case you want to use the property directly, instead of the attributes property is that if you define a method with the same name as the field you are accessing, this will generate a infinite recursion .

Example:

public function getNomeAttribute(){
   // Gera recursão, pois internamente será chamado o mesmo método
   return strtoupper($this->nome); 
}

So, the tip of using the property directly, is only valid if the Accessor name is different from the attribute accessed.

    
14.12.2016 / 17:07