简体   繁体   中英

Laravel Eloquent: How to store model values before saving?

I have a custom function within one of my models. It looks like this:

    public function newWithTeam($data, $team_id = false){

    $levels = Permissions::get_levels();

    $this->email    = $data['email'];
    $this->password = bcrypt($data['password']);
    $this->username = $data['username'];

    $this->save();

    $profile =  new Profile(['name' => $data['name'],'bio'  => $data['bio']]);
    $this->profile()->save($profile);
    }

Here, you can see I store the email , password and username as object properties, before hitting save()

Instead, I'd like to do this in one line, something like:

$this->store(['email' => $data['email], 'password' => $data['password], 'username' => $data['username']]);

$this->save();

I am aware that the create() method exists, but when I use this, the following line $this->profile()->save($profile); does not work properly. I think the create() function does not work the same as save() for some reason! Is there any equivalent to the store() function as above?

You can use the fill() method to achieve what you are looking for.

But before using it, you should know a few things.

Laravel models are protected against mass-assignment by security reasons, to use the fill() method you will need to define what properties of your model can be filled using the fillable or the guarded properties.

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class UserModel extends Model
{
    protected $fillable = ['email', 'password', 'username'];

    public function newWithTeam($data, $team_id = false){

        $levels = Permissions::get_levels();

        $this->fill([
            'email'    => $data['email'],
            'password' => bcrypt($data['password']),
            'username' => $data['username']
        ]);

        $this->save();

        $profile = new Profile([
            'name' => $data['name'],
            'bio' => $data['bio']
        ]);

        $this->profile()->save($profile);
    }
}

The fillable property functions like a white-list for mass-assignment. If you want the other way, you can use the guarded property that will function like a black-list. Which means that every column listed within the guarded property will not be available for mass-assignment and everything else will, it's your choice.

About your last statement, if you look at the implementation of the create() method you will find that it accepts a regular php array, while the save() method will accept an Eloquent Model instance. That's why create() will not work receiving your $profile variable.

I hope this helps.

The method that You're looking for is fill :

$this->fill([
    'email' => $data['email'],
    'password' => $data['password'],
    'username' => $data['username']]
);
$this->save();

You can use it for both creating and updating.

You can use fill directly:

$this->fill($data);
$this->save();

It will use the array keys as object attributes, so make sure you'll use the same.

Also, make sure you have set the $fillable in your model ( http://laravel.com/docs/eloquent#mass-assignment ):

class x extends Eloquent {
    protected $fillable = ['email','password','username'];
    ...
}

I'm not 100 % sure I understood you correctly, but it sounds like you want to make a oneliner update without screwing up the profile creation. In that case, you can simply use the update() method:

$this->update(['email' => $data['email], 'password' => bcrypt($data['password]), 'username' => $data['username']]);

That saves the new values for you.

So what happens when you run $this->create() ? Are you getting an error?

Consider that create() will return the new object that you created so you could try:

$user = $this->create([
    'email' => $data['email], 
    'password' => $data['password], 
    'username' => $data['username']
]);

$user->profile()->create([
    'name' => $data['name'],
    'bio'  => $data['bio']
]);

Didn't test this so see how you get on and leave a comment if you have any further issues. Happy coding!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM