rema96

Experience

90

0 Best Reply Awards

  • Member Since 3 Months Ago
  • 0 Lessons Completed
  • 0 Favorites

15th June, 2018

rema96 left a reply on Globally Eager Loading On Auth::user() To Prevent N+1 Problem • 3 months ago

I gave it a bit of thought and solved it.

As Cronix said, subscription() isn't returning a relationship. Therefor I made my own function sub() which returns a relationship, then I user $with attribute. protected $with = ['sub.plan.features'];

public function sub()
    {
        return $this->hasOne('App\Subscription');
    }

Thank you both for helping!

14th June, 2018

rema96 left a reply on Globally Eager Loading On Auth::user() To Prevent N+1 Problem • 3 months ago

But how does this work: App\User::find(1)->subscription()->plan->features->toArray()

If it isn't how should I override it because I am using cashier.

Here are all my modals:

https://gist.github.com/ilicmarko/3e8c56e38a82bfbae25844c726634587

rema96 left a reply on Globally Eager Loading On Auth::user() To Prevent N+1 Problem • 3 months ago

Please not this is Billable as I said it's using cashier so subscription relationship is implemented in Billable.php

/**
     * Get a subscription instance by name.
     *
     * @param  string  $subscription
     * @return \Laravel\Cashier\Subscription|null
     */
    public function subscription($subscription = 'default')
    {
        return $this->subscriptions->sortByDesc(function ($value) {
            return $value->created_at->getTimestamp();
        })
        ->first(function ($value) use ($subscription) {
            return $value->name === $subscription;
        });
    }

    /**
     * Get all of the subscriptions for the Stripe model.
     *
     * @return \Illuminate\Database\Eloquent\Relations\HasMany
     */
    public function subscriptions()
    {
        return $this->hasMany(Subscription::class, $this->getForeignKey())->orderBy('created_at', 'desc');
    }

rema96 left a reply on Globally Eager Loading On Auth::user() To Prevent N+1 Problem • 3 months ago

What part would you like to see? This is my personal project so I can share anything.

Here is my User modal for a starter:

<?php

namespace App;

use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Laravel\Cashier\Billable;


class User extends Authenticatable
{
    use Billable;
    use Notifiable;
    
    protected $fillable = [
        'name',
        'email',
        'password',
    ];

    protected $hidden = [
        'password',
        'remember_token',
    ];

    protected $with = ['subscription.plan.features'];

    public function isAdmin()
    {
        return $this->admin;
    }

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

    public function hasFeature($feature_id)
    {
        return $this->features()
                    ->where('slug', '=', $feature_id)
                    ->isNotEmpty();
    }

    public function subscriptionName()
    {
        if ($this->subscribed()) {
            $currPlanID = $this->subscription()->stripe_plan;
            $plan = Plan::where('id', '=', $currPlanID)->first();

            return $plan->name;
        }
        return null;
    }
}

rema96 left a reply on Globally Eager Loading On Auth::user() To Prevent N+1 Problem • 3 months ago

I forgot to state that I tried $with but with no luck...

I get:

BadMethodCallException thrown with message "Method Illuminate\Database\Query\Builder::with does not exist."

Stacktrace:
#57 BadMethodCallException in /home/vagrant/code/vendor/laravel/framework/src/Illuminate/Database/Query/Builder.php:2813
#56 Illuminate\Database\Query\Builder:__call in /home/vagrant/code/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Builder.php:558
#55 Illuminate\Database\Eloquent\Builder:getRelation in /home/vagrant/code/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Builder.php:518
#54 Illuminate\Database\Eloquent\Builder:eagerLoadRelation in /home/vagrant/code/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Builder.php:498
#53 Illuminate\Database\Eloquent\Builder:eagerLoadRelations in /home/vagrant/code/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Builder.php:466
#52 Illuminate\Database\Eloquent\Builder:get in /home/vagrant/code/vendor/laravel/framework/src/Illuminate/Database/Concerns/BuildsQueries.php:77
#51 Illuminate\Database\Eloquent\Builder:first in /home/vagrant/code/vendor/laravel/framework/src/Illuminate/Auth/EloquentUserProvider.php:51
#50 Illuminate\Auth\EloquentUserProvider:retrieveById in /home/vagrant/code/vendor/laravel/framework/src/Illuminate/Auth/SessionGuard.php:132
#49 Illuminate\Auth\SessionGuard:user in /home/vagrant/code/vendor/laravel/framework/src/Illuminate/Auth/GuardHelpers.php:36
#48 Illuminate\Auth\SessionGuard:authenticate in /home/vagrant/code/vendor/laravel/framework/src/Illuminate/Auth/AuthManager.php:292
#47 Illuminate\Auth\AuthManager:__call in /home/vagrant/code/vendor/laravel/framework/src/Illuminate/Auth/Middleware/Authenticate.php:57
#46 Illuminate\Auth\Middleware\Authenticate:authenticate in /home/vagrant/code/vendor/laravel/framework/src/Illuminate/Auth/Middleware/Authenticate.php:41
#45 Illuminate\Auth\Middleware\Authenticate:handle in /home/vagrant/code/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:151
#44 Illuminate\Pipeline\Pipeline:Illuminate\Pipeline\{closure} in /home/vagrant/code/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php:53
#43 Illuminate\Routing\Pipeline:Illuminate\Routing\{closure} in /home/vagrant/code/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/VerifyCsrfToken.php:67
#42 Illuminate\Foundation\Http\Middleware\VerifyCsrfToken:handle in /home/vagrant/code/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:151
#41 Illuminate\Pipeline\Pipeline:Illuminate\Pipeline\{closure} in /home/vagrant/code/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php:53
#40 Illuminate\Routing\Pipeline:Illuminate\Routing\{closure} in /home/vagrant/code/vendor/laravel/framework/src/Illuminate/View/Middleware/ShareErrorsFromSession.php:49
#39 Illuminate\View\Middleware\ShareErrorsFromSession:handle in /home/vagrant/code/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:151
#38 Illuminate\Pipeline\Pipeline:Illuminate\Pipeline\{closure} in /home/vagrant/code/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php:53
#37 Illuminate\Routing\Pipeline:Illuminate\Routing\{closure} in /home/vagrant/code/vendor/laravel/framework/src/Illuminate/Session/Middleware/StartSession.php:63
#36 Illuminate\Session\Middleware\StartSession:handle in /home/vagrant/code/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:151
#35 Illuminate\Pipeline\Pipeline:Illuminate\Pipeline\{closure} in /home/vagrant/code/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php:53
#34 Illuminate\Routing\Pipeline:Illuminate\Routing\{closure} in /home/vagrant/code/vendor/laravel/framework/src/Illuminate/Cookie/Middleware/AddQueuedCookiesToResponse.php:37
#33 Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse:handle in /home/vagrant/code/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:151
#32 Illuminate\Pipeline\Pipeline:Illuminate\Pipeline\{closure} in /home/vagrant/code/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php:53
#31 Illuminate\Routing\Pipeline:Illuminate\Routing\{closure} in /home/vagrant/code/vendor/laravel/framework/src/Illuminate/Cookie/Middleware/EncryptCookies.php:59
#30 Illuminate\Cookie\Middleware\EncryptCookies:handle in /home/vagrant/code/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:151
#29 Illuminate\Pipeline\Pipeline:Illuminate\Pipeline\{closure} in /home/vagrant/code/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php:53
#28 Illuminate\Routing\Pipeline:Illuminate\Routing\{closure} in /home/vagrant/code/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:104
#27 Illuminate\Pipeline\Pipeline:then in /home/vagrant/code/vendor/laravel/framework/src/Illuminate/Routing/Router.php:667
#26 Illuminate\Routing\Router:runRouteWithinStack in /home/vagrant/code/vendor/laravel/framework/src/Illuminate/Routing/Router.php:642
#25 Illuminate\Routing\Router:runRoute in /home/vagrant/code/vendor/laravel/framework/src/Illuminate/Routing/Router.php:608
#24 Illuminate\Routing\Router:dispatchToRoute in /home/vagrant/code/vendor/laravel/framework/src/Illuminate/Routing/Router.php:597
#23 Illuminate\Routing\Router:dispatch in /home/vagrant/code/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php:176
#22 Illuminate\Foundation\Http\Kernel:Illuminate\Foundation\Http\{closure} in /home/vagrant/code/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php:30
#21 Illuminate\Routing\Pipeline:Illuminate\Routing\{closure} in /home/vagrant/code/vendor/barryvdh/laravel-debugbar/src/Middleware/InjectDebugbar.php:65
#20 Barryvdh\Debugbar\Middleware\InjectDebugbar:handle in /home/vagrant/code/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:151
#19 Illuminate\Pipeline\Pipeline:Illuminate\Pipeline\{closure} in /home/vagrant/code/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php:53
#18 Illuminate\Routing\Pipeline:Illuminate\Routing\{closure} in /home/vagrant/code/vendor/fideloper/proxy/src/TrustProxies.php:57
#17 Fideloper\Proxy\TrustProxies:handle in /home/vagrant/code/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:151
#16 Illuminate\Pipeline\Pipeline:Illuminate\Pipeline\{closure} in /home/vagrant/code/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php:53
#15 Illuminate\Routing\Pipeline:Illuminate\Routing\{closure} in /home/vagrant/code/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php:31
#14 Illuminate\Foundation\Http\Middleware\TransformsRequest:handle in /home/vagrant/code/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:151
#13 Illuminate\Pipeline\Pipeline:Illuminate\Pipeline\{closure} in /home/vagrant/code/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php:53
#12 Illuminate\Routing\Pipeline:Illuminate\Routing\{closure} in /home/vagrant/code/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php:31
#11 Illuminate\Foundation\Http\Middleware\TransformsRequest:handle in /home/vagrant/code/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:151
#10 Illuminate\Pipeline\Pipeline:Illuminate\Pipeline\{closure} in /home/vagrant/code/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php:53
#9 Illuminate\Routing\Pipeline:Illuminate\Routing\{closure} in /home/vagrant/code/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ValidatePostSize.php:27
#8 Illuminate\Foundation\Http\Middleware\ValidatePostSize:handle in /home/vagrant/code/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:151
#7 Illuminate\Pipeline\Pipeline:Illuminate\Pipeline\{closure} in /home/vagrant/code/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php:53
#6 Illuminate\Routing\Pipeline:Illuminate\Routing\{closure} in /home/vagrant/code/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/CheckForMaintenanceMode.php:51
#5 Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode:handle in /home/vagrant/code/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:151
#4 Illuminate\Pipeline\Pipeline:Illuminate\Pipeline\{closure} in /home/vagrant/code/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php:53
#3 Illuminate\Routing\Pipeline:Illuminate\Routing\{closure} in /home/vagrant/code/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:104
#2 Illuminate\Pipeline\Pipeline:then in /home/vagrant/code/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php:151
#1 Illuminate\Foundation\Http\Kernel:sendRequestThroughRouter in /home/vagrant/code/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php:116
#0 Illuminate\Foundation\Http\Kernel:handle in /home/vagrant/code/public/index.php:55

rema96 started a new conversation Globally Eager Loading On Auth::user() To Prevent N+1 Problem • 3 months ago

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.

Edit Your Profile
Update

Want to change your profile photo? We pull from gravatar.com.