How To Find If There Is A Pivot Table Used In An Eloquent Scope Method?

- 1 answer

Currently I have 3 tables

  • users
    • id, name
  • discount
    • id, name, active
  • discount_user
    • discount_id, user_id, start, end

I need to find all the active discounts for a current user which are currently running based on the start and the end dates held on the pivot table.

I was hoping to be able to build a scopeActive method on the discount table to narrow down active discounts for the current user, but I only want the date range to be added if I'm coming from the user table to find the discounts:

$discounts = User::find(1)->discounts()->active()->get(); // within date range
$active = Discount::active()->get(); // without date range check

On the user table I've extended the relations to have an 'activeDiscounts' relation which works using:

public function activeDiscounts() {
    return $this->discounts()
            ->where('active', true)
            ->wherePivot('start', '>=', Carbon::now())
            ->wherePivot('end', '<=', Carbon::now());

Though this works, I don't think it's really best practice and would prefer to be able to use a scope on the discount.

Is there any way I can tell if I'm coming from the user table or through a pivot on the scope query? Also, if so, would I be able to see the User ID so I can use it in the pivot query?



To answer on your question: You could use arguments in scope, e.g:

$discounts = User::find(1)->discounts()->active(true)->get(); // within date range
$active = Discount::active()->get();


public function scopeActive($query, $withDates = false) {
    return $query
        ->where('active', true)
        ->when($withDates, function($query){
                ->wherePivot('start', '>=', Carbon::now())
                ->wherePivot('end', '<=', Carbon::now());

But I think that it is not better than your solution.

Also, you could use 2 different scopes.