0

I'm trying to extend the create() method on a model so that every time you call a create() it does some stuff before insert the row.

For example I have a Balance model, which has fields amount and ending_balance. I want to be able to only specify the amount when create() and then have the ending_balance automatically calculated within the model (ie by looking up the previous ending_balance)

I'd also like to be able to put all the create logic within a DB::transaction() so that I can lock the rows while doing the calculations.

I've added this to my model, but it never hits the dd() when creating.

class Balance extends Model
{
    use HasFactory;

    public static function create(array $attributes = [])
    {
        dd($attributes);
        // Calculate the ending_balance here 

        return parent::create($attributes);
    }
}
0

1 Answer 1

3

You might want to use Model events.

This link describes how to do it using closures: https://laravel.com/docs/8.x/eloquent#events-using-closures

the "created/creating" event might be what you are looking for. If things need to be recalculated, take a look at the updating/updated events.

 class Balance extends Model
    {
        protected static function booted()
        {
            static::created(function ($user) {
                // Calculate the fields value here
            });
        }
    }

I personally think overriding the create method is a little bit odd, and I've never seen anyone doing it. It might be not obvious for your teammates too. Just stick with events.

Another question was - how to do things in a transaction. Answer: use Laravel DB facade to run code in a transaction:

https://laravel.com/docs/8.x/database#database-transactions

DB::transaction(function () {
    Balance::create([...]);
    OtherMode::create([...]);
});

This will commit the transaction after the last line in the closure.

You can also manually control transactions:

DB::beginTransaction();
DB::rollBack();
DB::commit();
Sign up to request clarification or add additional context in comments.

3 Comments

creating event would probably be more appropriate but events looks like a good idea here
Thank you, I have now been able to do this using the creating event; however how would I put the whole create queries into a DB transaction?
@DavidB see an updated answer on how to deal with transactions

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.