0

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?

3 Answers 3

1

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

Sign up to request clarification or add additional context in comments.

1 Comment

This is exactly what I wanted, I didn't even knew about this method. btw I also realized we can also create a entry to database with the withDefault method as it also accepts a closure.
0

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

Comments

0

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.