Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Laravel 5 mutators only work when I create a record and not when I update a record

Hi I have created a mutator to only store digits on my phone numbers. Here is my code in my Profile Model.

public function setPhoneAttribute($phone)
{
    $this->attributes['phone'] = preg_replace("/[^0-9]/","",$phone);
}

This works when I create a new record, but if I update the record it does not work. My question is how do I execute the Mutator on both create and update?

Here is how I update and create in my controller:

namespace App\Http\Controllers;
use App\Http\Requests;
use App\Http\Requests\ProfileRequest;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Auth;
use App\Profile;

class ProfileController extends Controller {

    public function create(ProfileRequest $request)
    {
        // Check if the user does not have a profile yet
        if(!Auth::user()->profile()->first()){

            // Save to database
            $saveToDatabase = Auth::user()->profile()->create($request->all()); 

            return $saveToDatabase;
        }
    }

    public function update(Profile $profile, ProfileRequest $request)
    {

        // Save to database
        $saveToDatabase = Auth::user()->profile()->update($request->all());

        return $saveToDatabase;
    }
}
like image 586
OsvyG Avatar asked Mar 27 '15 17:03

OsvyG


People also ask

What are accessors and mutators explain with code snippets in Laravel?

Laravel accessors and mutators are custom, user defined methods that allow you to format Eloquent attributes. Accessors are used to format attributes when you retrieve them from the database, while mutators format the attributes before saving them to the database.

What are mutators and accessors in Laravel?

Accessors and mutators allow you to format Eloquent attributes when retrieving them from a model or setting their value. For example, you may want to use the Laravel encrypter to encrypt a value while it is stored in the database, and then automatically decrypt the attribute when you access it on an Eloquent model.

What is fillable in Laravel?

The fillable property is used inside the model. It takes care of defining which fields are to be considered when the user will insert or update data. Only the fields marked as fillable are used in the mass assignment. This is done to avoid mass assignment data attacks when the user sends data from the HTTP request.

What is eloquent ORM in Laravel?

Eloquent is an object relational mapper (ORM) that is included by default within the Laravel framework. An ORM is software that facilitates handling database records by representing data as objects, working as a layer of abstraction on top of the database engine used to store an application's data.


2 Answers

Here's what's happening:

Auth::user()->profile()->create($request->all()) calls the create method on your relationship (HasOneOrMany). This method then creates a new instance of the related model. This is important because obviously attribute mutators are only used when the record is created through the model.

However the relationship object doesn't have any update method. (It also wouldn't make sense to have one...). So what's happening instead is, when you do Auth::user()->profile()->update($request->all()). The update call get's proxied off to a query builder instance (that matches the relationship). This results in something like this being executed:

UPDATE profiles SET foo = 'bar' WHERE [relationship conditions]

It doesn't use the model at all. Therefore the mutator doesn't work.

Instead you have to call the update method on the actual related model. You can access it by just calling the relation as a property like this:

$saveToDatabase = Auth::user()->profile->update($request->all());
//                                    ^^
//                               no parentheses

If the Profile model is injected correctly you actually might also just use that though:

public function update(Profile $profile, ProfileRequest $request)
{
    // Save to database
    $saveToDatabase = $profile->update($request->all());
    return $saveToDatabase;
}
like image 131
lukasgeiter Avatar answered Sep 16 '22 14:09

lukasgeiter


Using this code instead of your code

$saveToDatabase = Auth::user()->profile->update($request->all());
like image 30
mininoz Avatar answered Sep 19 '22 14:09

mininoz