Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

vincent15000's avatar

Model Policy to prevent deleting ?

Hello,

A price has always a level, a funding, a type and a state.

A level, a funding, a type and a state have many sessions.

But a sessions has no price relationship because the amount is directly written in a float column (for convenience, if the amounts change one day or another, the amounts won't change in the past sessions).

So a price can't be deleted if it has at least one session which has the same level, funding, type and state than the price.

How can I write this in my policy ?

I tried something like that to begin and test.

// Delete policy
return $price->has('level.sessions')->count() == 0;

I'd better like something like this.

/**
 * Determine whether the user can delete the model.
 *
 * @param  \App\Models\User  $user
 * @param  \App\Models\Price  $price
 * @return \Illuminate\Auth\Access\Response|bool
 */
public function delete(User $user, Price $price)
{
    return $price->has('level.sessions', function ($query) use ($price) {
        $query->where('level_id', $price->level_id);
    });
}

But it doesn't work.

Then I have to add the same test for the funding, the type and the state.

Thanks for your help.

Vincent

0 likes
16 replies
tykus's avatar

Is this the start of a riddle? 🫤

1 like
vincent15000's avatar

@tykus Sorry, I thought I have given enough informations, I thought anyone would have understood. Which information can I give more ?

vincent15000's avatar

@tykus Thank you for your answer, this idea of riddle is excellent, I just read again my post and I have the giggles and I can't stop with the giggles.

1 like
vincent15000's avatar

@tykus Sorry for yesterday, I'm sure I was tired and when I read again my post, I noticed it looks like a riddle with some clues, it was very amusing, all the more because I love riddles, escape games, treasure hunts, ...

vincent15000's avatar

I have found this solution.

/**
 * Determine whether the user can delete the model.
 *
 * @param  \App\Models\User  $user
 * @param  \App\Models\Price  $price
 * @return \Illuminate\Auth\Access\Response|bool
 */
public function delete(User $user, Price $price)
{
    return Session::
        where('level_id', $price->level_id)
        ->where('funding_id', $price->funding_id)
        ->where('type_id', $price->type_id)
        ->where('state_id', $price->state_id)
        ->count() == 0;
}

But I think that if I have a large quantity of lines, it will send a query for each model and it can be heavy.

Is there a way to improve this policy ?

khaledw62's avatar
Level 6

or you can use

$query->withExists(['sessions' => fn($query) => $query
        ->whereCoulmn('prices.level_id', 'sessions.level_id')
        ->whereCoulmn('prices.funding_id', 'sessions.funding_id')
        ->whereCoulmn('prices.type_id', 'sessions.type_id')
        ->whereCoulmn('prices.state_id', 'sessions.state_id');
]);

and then in the delete policy

public function delete(User $user, Price $price)
{
    return isset($price->sessions_exists) ? !$price->sessions_exists  :  Session::
        where('level_id', $price->level_id)
        ->where('funding_id', $price->funding_id)
        ->where('type_id', $price->type_id)
        ->where('state_id', $price->state_id)
        ->count() == 0;
}
1 like
vincent15000's avatar

@khaledw62 Your idea is very good and I think that the $price->sessions_exists is sufficient for me to allow or not to delete the price. I will test this right now.

vincent15000's avatar

@khaledw62 The only problem is that a price has no session with a direct relationship. It has sessions through a level, a funding, a type and a state.

Snapey's avatar

a side note, if 'price' is currency, never use floats

1 like
vincent15000's avatar

@Snapey I use usually use decimal. Effectively I have written float, but it's a decimal.

Snapey's avatar

@vincent15000 use ints in lowest traded denomination

decimal is your database storage. Php doesn't have decimal datatype, it uses floats

1 like
Snapey's avatar

@vincent15000 like €123,45 is stored as 12345 cents

If it were stocks, or something that someone might buy in large volumes then it might be necessary to go lower than cents, eg our price is $0.0325 per SMS message, so store it as 325 and know that it is hundredths of a penny

1 like
vincent15000's avatar

@Snapey So you suggest to handle all money values as integers in the code ? I never did this.

vincent15000's avatar

@Snapey I already knew the problem with the approximations.

With PHP, when I retrieve some numbers from the database, I even not take attention to the type.

I didn't code any app with money values except one for me.

Now I will take attention to the type of the variables in PHP.

Thank you @snapey ;).

Please or to participate in this conversation.