Globally Eager Loading on Auth::user() to prevent n+1 problem

Posted 5 months ago by rema96

I am building a subscription based site, I am using cashier and I got everything setup also I have a plans table that represents what I have on Stripe, this is simply because I want to list price plans. Furthermore I have features, features and plans are connected with a pivot table n-m.

The problem I am having I would like to know if user has a certain feature, I get this bases on his subscription and then his plan connected to that subscription.

In users model I made a simple function to test this:

public function features()
    {
        return User::join('subscriptions', 'users.id', '=', 'subscriptions.user_id')
            ->join('plans', 'plans.id', '=', 'subscriptions.stripe_plan')
            ->join('feature_plan', 'feature_plan.plan_id', '=', 'plans.id')
            ->join('features', 'features.id', '=', 'feature_plan.feature_id')
            ->where('users.id', '=', $this->id)
            ->get();
    }

With this I get all the features of that user, I also have my relationships setup in Laravel so this App\User::find(1)->subscription()->plan->features->toArray() also works.

Here is a problem if I call hasFeature() function in a loop or even multiple times on the page I will get the famous n+1 problem.

public function hasFeature($feature_id)
    {
        return $this->features() // This will call the function above
                    ->where('slug', '=', $feature_id)
                    ->isNotEmpty();
    }

I know the way to solve this is with eager loading but how can I globally eager load this information to my user?

One idea I had was retrieve all the features in User model constructor and assign it to a variable in the class, but I am not really sure if that will work.

Also is there a way to optimize this even more, like cache it so it doesn't make a request every single page load?

Please sign in or create an account to participate in this conversation.

Laracasts Mascot

Hi, Have We Met Yet?

Did you know that, in addition to the forum, Laracasts includes well over 1000 lessons on modern web development? All for the price of one lunch out per month.

Sign Me Up

Channels

Reply to

Use Markdown with GitHub-flavored code blocks.