Search code examples
phpeloquentlaravel-6accessor

Laravel 6.11: Shopping cart HasMany::fisrt() in Accessor not working


EDIT: typos corrected (made while translating some of the code)

I'm building a shopping cart with Laravel 6.11 (MAMP). I am getting a couple of errors that are driving me nuts. Please help! First I'll give you the code, afterwards the errors:

Table carts:

id
order_date
arrived_date
status
user_id

Table cart_details:

id
cart_id
product_id
quantity
discount

Please note that the two tables are EMPTY at this point, no records inserted just yet.

A cart can have many cartdetails. So in Cart.php I have:

class Cart extends Model
{
    public function details()
    {
        return $this->hasMany(CartDetail::class);
    }
}

CartDetailController contains:

class CartDetailController extends Controller
{
    //let's insert data in  cart_details so the order can be created
    public function store(Request $request)
    {

        $cartDetail = new CartDetail();

        $cartDetail->cart_id = auth()->user()->cart_identification;/* cart_id from the logged user. In User.php I have getCartIdentifitacionAttribute, I'm going to put the code right after this */

        $cartDetail->product_id = $request->product_id;
        $cartDetail->quantity = $request->quantity;

        $cartDetail->save();

        return back();
    }
}

In User.php I have:

  public function carts()
    {
        return $this->hasMany(Cart::class); //a user can have many carts
    }
    public function getCartIdentificationAttribute()
    {
        $cart = $this->carts()->where('status','Active')-> first();

        if($cart)
        {
            return $cart->id;
        }
        else// if there's no cart, let's create a new one
        {
            $cart = new Cart();
            $cart->status = 'Active';
            $cart->user_id = $this->id;
            $cart->save();
            return $cart->id;

       }
    }

The .blade (which will show the administrator the details of the order):

@foreach (auth()->user()->cart_identification->details as $detail)

      <ul>
            <li>{{ $detail }}</li>
        </ul>
@endforeach

And now the errors, two... certainly related :(

  1. In a product page, after hitting "Add to the Cart":

    BadMethodCallException Call to undefined method Illuminate\Database\Eloquent\Relations\HasMany::fisrt()

If I print $this->carts()->where('status','Active') it works, it is when I add ->fist() that the error shows

  1. When accesing the blade as an administrator would do to deal with the order:

    Facade\Ignition\Exceptions\ViewException Call to undefined method Illuminate\Database\Eloquent\Relations\HasMany::fisrt() (View: /Applications/MAMP/htdocs/app-shop/resources/views/home.blade.php)

If I print auth()->user() it works, it is auth()->user()->cart_identification that causes the error.

What am I missing??

Thanks a ton!!


Solution

  • I think you have a typo error.

    It should be

    $cart = $this->carts()->where('status','Active')->first();
    

    Not

     $cart = $this->carts()->where('status','Active')->fisrt();
    

    And in your model change your code to this.

    public function scopeCartIdentification()
        {
            $cart = $this->carts()->where('status','Active')->first();
    
            if($cart)
            {
                return $cart->id;
            }
            else// if there's no cart, let's create a new one
            {
                $cart = new Cart();
                $cart->status = 'Active';
                $cart->user_id = $this->id;
                $cart->save();
                return $cart->id;
    
           }
    }
    

    and call in to your controller like this

    public function store(Request $request)
        {
    
            $cartDetail = new CartDetail();
    
            $cartDetail->cart_id = auth()->user()->CartIdentification();/* cart_id from the logged user. In User.php I have getCartIdentifitacionAttribute, I'm going to put the code right after this */
    
            $cartDetail->product_id = $request->product_id;
            $cartDetail->quantity = $request->quantity;
    
            $cartDetail->save();
    
            return back();
        }