Home > database >  Laravel auto create relation entry with default data
Laravel auto create relation entry with default data

Time:05-23

I'm trying to make a wallet system in my Laravel application.

My database has the default users table and each user has one wallet.

like this:

// User model
public function wallet()
{
    return $this->hasOne(Wallet::class);
}

I want whenever I query wallet like:

$user->wallet

I want if the user doesn't have wallet a new wallet should be created automatically with default values.

How to do this in a organized and efficient manner?

CodePudding user response:

By "I want if the user doesn't have wallet a new wallet should be created automatically with default values" if you mean that you want some default values when using $user->wallet on frontend to avoid conditionals, you can use the handy withDefault() as below:

/**
 * Get the wallet for the user.
 */
public function wallet()
{
    return $this->hasOne(Wallet::class)->withDefault([
        //Default values here
        //This will not persist or create a record in database
        // It will just return an instance of Wallet with default values defined here instead of null when a user doesn't have a Wallet yet
        // It will help avoid conditionals say in frontend view
    ]);
}

You can read more at DefaultModel - Lavavel Docs

However if you want every user to have a default Wallet you can make use of Model hooks and create a Wallet for each user when a record is created.


class User extends Model
{
    public static function booted()
    {
        static::created(function($user){
            $user->wallet()->create([
                //Default values here...
            ]);
        });
    }

    // Rest of the User Model class code...
}

You can read more at Model Events - Laravel Docs

CodePudding user response:

I don't know but you should have a look to this

//copy attributes from original model
$newRecord = $original->replicate();
// Reset any fields needed to connect to another parent, etc
$newRecord->some_id = $otherParent->id;
//save model before you recreate relations (so it has an id)
$newRecord->push();
//reset relations on EXISTING MODEL (this way you can control which ones will be loaded
$original->relations = [];
//load relations on EXISTING MODEL
$original->load('somerelationship', 'anotherrelationship');
//re-sync the child relationships
$relations = $original->getRelations();
foreach ($relations as $relation) {
    foreach ($relation as $relationRecord) {
        $newRelationship = $relationRecord->replicate();
        $newRelationship->some_parent_id = $newRecord->id;
        $newRelationship->push();
    }
}

CodePudding user response:

1) if not exists
public function wallet()
{
    return $this->hasOne(Wallet::class)->withDefault([
        'name' => 'Wallet Name',
    ]);
}

2) or force insert when user created please use observer|model boot


    protected static function boot()
    {
        parent::boot();

        static::created(static function (self $user) {
            $wallet = new Wallet(['name' => 'Wallet Name']);
            $user->wallet()->save($wallet);
        });
   }

  • Related