Luigi Caradonna
Luigi Caradonna

Reputation: 1064

Laravel 5.5 - Prevent additional attribute to be used during model update

The users table, besides others, have these fields: username, first_name, last_name. Each user can decide whether to show the username or the full name (first + last). This choice is stored inside a "settings" table.

To not perform repeated queries and calls to a function any time I need to show the name, I add the name to display to the user object as it is created, like $user->display_name = ... according to the user's choice.

The problem is that when the user updates the profile, Laravel tries to save this name inside a display_name field into the users' table, which doesn't exist and returns a 500 error. That also happens when the user tries to logout.

Is it possible to avoid that Laravel tries to store that value inside the database?

As suggested in other discussions I have already tried to give a default value to the attribute inside the User model, I've tried to set the attribute as protected, but nothing did work.

Upvotes: 1

Views: 868

Answers (1)

Tim Lewis
Tim Lewis

Reputation: 29278

This is where the get{...}Attribute() function of a Model comes in handy. Say you want to access $user->full_name without actually saving full_name to the database. Since you have first_name and last_name, you can declare on your User model:

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

Laravel will parse what's between get and Attribute into a property available on the model, in this case either $user->full_name or $user->fullName.

To translate this to your use case, you can use something like:

In your User.php model:

public function getDisplayNameAttribute(){
   if($this->settings == "use_full_name"){
       return $this->first_name." ".$this->last_name;
   } else if($this->settings == "use_username"){
       return $this->username;
   }
   return "Not Configured...";
}

Note: You'll have to configure your if statements to determine what to return based on your settings.

Somewhere in a controller or view, you can call $user->display_name to have one of 3 things (determined by the logic/return statements above) displayed:

public function example(){
    $user = User::first();
    dd($user->display_name); 
    // $user->first_name." "$user->last_name, $user->username or "Not Configured..."
}

By doing this, when you access your $user, it will have a display_name property available that doesn't actually exist on the model, so you won't run into issues should you call $user->save();

Upvotes: 0

Related Questions