Is it mandatory to visit Mutator/Accessor?

Asked

Viewed 141 times

1

I just faced a problem in Laravel 5.1.

Suppose 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

UPPERCASE NAME

But let’s assume I did a JOIN for Eloquent and nay select the field name table Users.

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 function I defined in the Model Users.

To make no mistake, I have to make 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 on all.

The question is:

Is it really necessary ? There is no other way ?

  • in that case it is not mutators is serialization if I’m not mistaken? I’m basing it on the spelling !!!

  • In that case, it’s not Mutators, and yes Accessors.

1 answer

3


A little correction: It’s not called Mutator, and yes Accessor.

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

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

The use of Accessor is limited to cases where you need a specific formatting of a given field of your table. There are possibilities of returning other types of information, but usually you will want to use them to work with table-specific data.

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

In your case, the mistake Undefined Indexoccurs because the field has not been selected.

Answering your question: Yes, you would need to check every time, what not my view is not a problem, since you define a method only once, but reuse 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 observation I make in case you want to use the property directly instead of the property attributes is that if you define a method with the same name of the field you are accessing, it will generate a infinite recursiveness.

Example:

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

Then, the hint to use the property directly, only valid if the Accessor name is different from the attribute accessed.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.