Home > Software design >  Larvel model to not auto generated Id if id is provided
Larvel model to not auto generated Id if id is provided

Time:01-29

Newbie question here, I'm having an employee/profile model, where I have a boot function to create a user on the creation of the employee model.

public static function boot()
{
    parent::boot();
    static::created(function($model)
    {
       $User = new \App\Models\User;
         $User->id = $model->id;
          $User->name = $model->first_name.' '.$model->last_name;
          $User->email = $model->work_email;
          $User->save();

    });

while checking the DB i notice it's not picking the employee ID (UUID) and saving the same id as user ID

$User->id = $model->id;

what I'm doing wrong here ?

i have found that i can update it after saving by adding

public static function boot()
{
    parent::boot();
    static::created(function($model)
    {
       $User = new \App\Models\User;
         $User->id = $model->id;
          $User->name = $model->first_name.' '.$model->last_name;
          $User->email = $model->work_email;
          $User->save();
          $User->id = $model->id;
          $User->save();


    });
}

is there is way to do it without saving two times?

CodePudding user response:

You are fundamentally misunderstanding how database relations should be created. You do not indicate that two entries are related by giving them the same ID.

You do it by creating a foreign key between the two tables in your migration:

public function up()
{
    Schema::create('users', function (Blueprint $table) {
        $table->id();
        $table->foreignId('employee_id')->constrained('employees');
        $table->string('name');
        $table->string('email');
    });
}

And then creating a relationship in your ORM.

class User extends Authenticatable {
    public function employee() {
        return $this->belongsTo(Employee::class);
    }
}
class Employee extends Model {
    public function user() {
        return $this->hasOne(User::class);
    }
}

And then your event handler looks like this:

public static function boot()
{
    parent::boot();
    static::created(function ($model) {
       $u = User::make([
           'name' => $model->first_name . ' ' . $model->last_name,
           'email' => $model->work_email,
       ]);
       $u->employee = $model;
       $u->save();
    });
}

Now you have related user to employee, such that you can do things like this:

$user = User::find(123);
echo $user->employee->first_name;

CodePudding user response:

Try using forceCreate(...) instead.

Save a new model and return the instance. Allow mass-assignment.

\App\Models\User::forceCreate([
    "id" => $model->id,
    "name" => $model->first_name . ' ' . $model->last_name,
    "email" => $model->work_email,
]);

Addendum

Alternatively, you may use forceFill(...)

Fill the model with an array of attributes. Force mass assignment.

(new \App\Models\User)->forceFill([
    "id" => $model->id,
    "name" => $model->first_name . ' ' . $model->last_name,
    "email" => $model->work_email,
])->save();

CodePudding user response:

If you create a new user, you shouldn't add id. If you want to update an existing user, you should use for example find instead of creating a new model object

  •  Tags:  
  • Related