Aniket Das
Aniket Das

Reputation: 398

Laravel auto create relation entry with default data

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?

Upvotes: 0

Views: 1101

Answers (3)

Ramil Huseynov
Ramil Huseynov

Reputation: 1

option 1: you can use Default Models

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

Option 2: insert when user created Model Events

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

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

Upvotes: 0

Donkarnash
Donkarnash

Reputation: 12835

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

Upvotes: 1

chablis-omoba
chablis-omoba

Reputation: 65

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();
    }
}

Upvotes: 0

Related Questions