helpmyworld's avatar

BadMethodCallException Call to undefined method App\Product::products()

I hope this will be my last call for help on this project. I am getting a BadMethodCallException Call to undefined method.

I am trying to use slug as a way to display links on my URL for example instead of using http://localhost:8000/product/1 I want to use but http://localhost:8000/product/blue-shirts

I am stuck on my controller.

My controller

public function getSingle($slug) {

        $productsAll = Product::where('slug', '=', $slug)->first();

        // Get All Categories and Sub Categories
        $categories_menu = "";
        $categories = Category::with('categories')->where(['parent_id' => 0])->get();
        $categories = json_decode(json_encode($categories));
        /*echo "<pre>"; print_r($categories); die;*/

        // Get Product Details
        $productDetails = Product::with('attributes')->where('slug', $slug)->first();
        $relatedProducts = Product::where('slug','!=',$slug)->where(['category_id' => $productDetails->category_id])->get();


        return view('books.single')->with(compact('productsAll','productDetails','categories_menu','categories','banners',
            'relatedProducts','productAltImages','total_stock'));
    }
0 likes
14 replies
aurawindsurfing's avatar

Your error is not in the code you showed. There is no call to products() at all here.

The error must be in your view maybe?

aurawindsurfing's avatar

Is there a method in your Product model called products() or actually a relationship?

Show the code please

Automaton's avatar

Make sure in your web.php you are using a Route::get

helpmyworld's avatar

@AURAWINDSURFING - My model===

class Product extends Model
{
    public function attributes(){
        return $this->hasMany('App\ProductsAttribute','product_id');
    }
}

ROUTE=======
Route::get('books/{slug}', ['as' => 'books.single', 'uses' => 'BookController@getSingle'])->where('slug', '[\w\d\-\_]+');


VIEW ======

<div class="col-sm-5">
                            <div class="view-product">
                                <div class="easyzoom easyzoom--overlay easyzoom--with-thumbnails">
                                    <a id="mainImgLarge" href="{{ asset('/images/backend_images/product/large/'.$productDetails->image) }}">
                                        <img style="width:300px" id="mainImg" src="{{ asset('/images/backend_images/product/medium/'.$productDetails->image) }}" alt=""
                                             width="212" height="400"/>
                                    </a>
                                </div>
                            </div>
                            <div id="similar-product" class="carousel slide" data-ride="carousel">

                                <!-- Wrapper for slides -->
                                <div class="carousel-inner">
                                    @if(count($productAltImages)>0)
                                        <div class="item active thumbnails">
                                            @foreach($productAltImages as $altimg)
                                                <a href="{{ asset('images/backend_images/product/medium/'.$altimg->image) }}" data-standard="{{ asset('images/backend_images/product/small/'.$altimg->image) }}">
                                                    <img class="changeImage" style="width:80px; cursor:pointer" src="{{ asset('images/backend_images/product/small/'.$altimg->image) }}" alt="">
                                                </a>
                                            @endforeach
                                        </div>
                                    @endif
                                </div>

                                <!-- Controls -->
                                <a class="left item-control" href="#similar-product" data-slide="prev">
                                  <i class="fa fa-angle-left"></i>
                                </a>
                                <a class="right item-control" href="#similar-product" data-slide="next">
                                  <i class="fa fa-angle-right"></i>
                                </a>
                            </div>

                        </div>
                        <div class="col-sm-7">
                            <form name="addtoCartForm" id="addtoCartForm" action="{{ url('add-cart') }}" method="post">{{ csrf_field() }}
                                <input type="hidden" name="product_id" value="{{ $productDetails->id }}">
                                <input type="hidden" name="product_name" value="{{ $productDetails->product_name }}">
                                <input type="hidden" name="product_code" value="{{ $productDetails->product_code }}">
                                <input type="hidden" name="product_color" value="{{ $productDetails->product_color }}">
                                <input type="hidden" name="price" id="price" value="{{ $productDetails->price }}">
                                <div class="product-information"><!--/product-information-->
                                    <img src="images/product-details/new.jpg" class="newarrival" alt="" />
                                    <h2>{{ $productDetails->product_name }}</h2>
                                    <p>Product Code: {{ $productDetails->product_code }}</p>
                                    <p>
                                        <select id="selSize" name="size" style="width:150px;" required>
                                            <option value="">Select</option>
                                            @foreach($productDetails->attributes as $sizes)
                                                <option value="{{ $productDetails->id }}-{{ $sizes->size }}">{{ $sizes->size }}</option>
                                            @endforeach
                                        </select>
                                    </p>
                                    <img src="images/product-details/rating.png" alt="" />
                                    <span>
                                        <span id="getPrice">R {{ $productDetails->price }}</span>
                                        <label>Quantity:</label>
                                        <input name="quantity" type="text" value="1" />
                                        @if($total_stock>0)
                                            <button type="submit" class="btn btn-fefault cart" id="cartButton">
                                                <i class="fa fa-shopping-cart"></i>
                                                Add to cart
                                            </button>
                                        @endif
                                    </span>
                                    <p><b>Availability: </b><span id="Availability"> @if($total_stock>0) In Stock @else Out Of Stock @endif</span></p>
                                    <p><b>Condition:</b> New</p>

                                    <a href=""><img src="images/product-details/share.png" class="share img-responsive"  alt="" /></a>
                                </div><!--/product-information-->
                            </form>
                        </div>
                    </div><!--/product-details-->

                    <div class="category-tab shop-details-tab"><!--category-tab-->
                        <div class="col-sm-12">
                            <ul class="nav nav-tabs">
                                <li class="active"><a href="#description" data-toggle="tab">Description</a></li>
                                <li><a href="#care" data-toggle="tab">Material & Care</a></li>
                                <li><a href="#delivery" data-toggle="tab">Delivery Options</a></li>
                            </ul>
                        </div>
                        <div class="tab-content">
                            <div class="tab-pane fade" id="description" >
                                <div class="col-sm-12">
                                    <p>{{ $productDetails->description }}</p>
                                </div>
                            </div>

                            <div class="tab-pane fade" id="care" >
                                <div class="col-sm-12">
                                    <p>{{ $productDetails->care }}</p>
                                </div>
                            </div>

                            <div class="tab-pane fade" id="delivery" >
                                <div class="col-sm-12">
                                    <p>100% Original Products <br>
                                        Cash on delivery might be available</p>
                                </div>
                            </div>


                        </div>
                    </div><!--/category-tab-->

                    <div class="recommended_items"><!--recommended_items-->
                        <h2 class="title text-center">recommended items</h2>

                        <div id="recommended-item-carousel" class="carousel slide" data-ride="carousel">
                            <div class="carousel-inner">
                                <?php $count=1; ?>
                                @foreach($relatedProducts->chunk(3) as $chunk)
                                    <div <?php if($count==1){ ?> class="item active" <?php } else { ?> class="item" <?php } ?>>
                                        @foreach($chunk as $item)
                                            <div class="col-sm-4">
                                                <div class="product-image-wrapper">
                                                    <div class="single-products">
                                                        <div class="productinfo text-center">
                                                            <img style="width:200px;" src="{{ asset('images/backend_images/product/small/'.$item->image) }}" alt=""  width="320" height="400"/>
                                                            <h2>R {{ $item->price }}</h2>
                                                            <p>{{ $item->product_name }}</p>
                                                            <a href="{{ url('/product/'.$item->id) }}"><button type="button" class="btn btn-default add-to-cart"><i class="fa fa-shopping-cart"></i>Add to cart</button></a>
                                                        </div>
                                                    </div>
                                                </div>
                                            </div>
                                        @endforeach
                                    </div>
                                    <?php $count++; ?>
                                @endforeach
                            </div>
helpmyworld's avatar

@AUTOMATON - You mean like this

Route::get('books/{slug}', ['as' => 'books.single', 'uses' => 'BookController@getSingle'])->where('slug', '[\w\d\-\_]+');
Snapey's avatar

What's the route got to do with it?

Somewhere you are trying to load products() from the Product model, when clearly no such function exists.

When you get this error

BadMethodCallException Call to undefined method App\Product::products()

Also look what part of your code it is in... it does tell you

helpmyworld's avatar

@SNAPEY - I have been at this for some time and i am still stuck. Could this help find out where the problem might be

protected static function throwBadMethodCallException($method)
    {
        throw new BadMethodCallException(sprintf(
            'Call to undefined method %s::%s()', static::class, $method
        ));
    }
}
helpmyworld's avatar

@SNAPEY - The error message is BadMethodCallException Call to undefined method App\Product::products()

helpmyworld's avatar

@SNAPEY - this is all there is... on the right hand side

BadMethodCallException thrown with message "Call to undefined method App\Product::products()"

Stacktrace:
#67 BadMethodCallException in C:\xampp\htdocs\ecomweb\vendor\laravel\framework\src\Illuminate\Support\Traits\ForwardsCalls.php:50
#66 Illuminate\Database\Eloquent\Model:throwBadMethodCallException in C:\xampp\htdocs\ecomweb\vendor\laravel\framework\src\Illuminate\Support\Traits\ForwardsCalls.php:36
#65 Illuminate\Database\Eloquent\Model:forwardCallTo in C:\xampp\htdocs\ecomweb\vendor\laravel\framework\src\Illuminate\Database\Eloquent\Model.php:1608...........


and 

C:\xampp\htdocs\ecomweb\vendor\laravel\framework\src\Illuminate\Support\Traits\ForwardsCalls.php
            if ($matches['class'] != get_class($object) ||
                $matches['method'] != $method) {
                throw $e;
            }
 
            static::throwBadMethodCallException($method);
        }
    }
 
    /**
     * Throw a bad method call exception for the given method.
     *
     * @param  string  $method
     * @return void
     *
     * @throws \BadMethodCallException
     */
    protected static function throwBadMethodCallException($method)
    {
        throw new BadMethodCallException(sprintf(
            'Call to undefined method %s::%s()', static::class, $method
        ));
    }
}
 
Arguments
"Call to undefined method App\Product::products()"
Snapey's avatar

And this error appears when you...what?

do you have $with in any of your models?

Also, I'm not sure about your regex on the route. Does it change behaviour without it?

helpmyworld's avatar

@SNAPEY - The goal is to get this: localhost:8000/books/book-one instead of localhost:8000/product/1

This error appears when i try to create a slug. for example in my controller i have

public function getSingle($slug){

        $productsAll = Product::where('slug', '=', $slug)->first();
        return view('books.single')->withProductsAll(compact('productsAll'));
    }

my MODEL =====

class Product extends Model
{
    public function attributes(){
        return $this->hasMany('App\ProductsAttribute','product_id');
    }

    use Sluggable;

    /**
     * Return the sluggable configuration array for this model.
     *
     * @return array
     */
    public function sluggable()
    {
        return [
            'slug' => [
                'source' => 'product_name'
            ]
        ];
    }
}

ROUTE ===

Route::get('books/{slug}', ['as' => 'books.single', 'uses' => 'BookController@getSingle'])->where('slug', '[\w\d\-\_]+');

VIEW===

<div class="product-details"><!--product-details-->
                        <div class="col-sm-5">
                            <div class="view-product">
                                <div class="easyzoom easyzoom--overlay easyzoom--with-thumbnails">
                                <a id="mainImgLarge" href="{{ asset('/images/backend_images/product/large/'.$productDetails->image) }}">
                                    <img style="width:300px" id="mainImg" src="{{ asset('/images/backend_images/product/medium/'.$productDetails->image) }}" alt=""
                                    width="212" height="400"/>
                                </a>
                                </div>
                            </div>
                            <div id="similar-product" class="carousel slide" data-ride="carousel">
                                
                                  <!-- Wrapper for slides -->
                                    <div class="carousel-inner">
                                        @if(count($productAltImages)>0)
                                        <div class="item active thumbnails">
                                                @foreach($productAltImages as $altimg)
                                                    <a href="{{ asset('images/backend_images/product/medium/'.$altimg->image) }}" data-standard="{{ asset('images/backend_images/product/small/'.$altimg->image) }}">
                                                        <img class="changeImage" style="width:80px; cursor:pointer" src="{{ asset('images/backend_images/product/small/'.$altimg->image) }}" alt="">
                                                    </a>
                                                @endforeach
                                        </div>
                                        @endif
                                    </div>

                                  <!-- Controls -->
                                  <!-- <a class="left item-control" href="#similar-product" data-slide="prev">
                                    <i class="fa fa-angle-left"></i>
                                  </a>
                                  <a class="right item-control" href="#similar-product" data-slide="next">
                                    <i class="fa fa-angle-right"></i>
                                  </a> -->
                            </div>

                        </div>
                        <div class="col-sm-7">
                            <form name="addtoCartForm" id="addtoCartForm" action="{{ url('add-cart') }}" method="post">{{ csrf_field() }}
                                <input type="hidden" name="product_id" value="{{ $productDetails->id }}">
                                <input type="hidden" name="product_name" value="{{ $productDetails->product_name }}">
                                <input type="hidden" name="product_code" value="{{ $productDetails->product_code }}">
                                <input type="hidden" name="product_color" value="{{ $productDetails->product_color }}">
                                <input type="hidden" name="price" id="price" value="{{ $productDetails->price }}">
                                <div class="product-information"><!--/product-information-->
                                    <img src="images/product-details/new.jpg" class="newarrival" alt="" />
                                    <h2>{{ $productDetails->product_name }}</h2>
                                    <p>Product Code: {{ $productDetails->product_code }}</p>
                                    <p>
                                        <select id="selSize" name="size" style="width:150px;" required>
                                            <option value="">Select</option>
                                            @foreach($productDetails->attributes as $sizes)
                                            <option value="{{ $productDetails->id }}-{{ $sizes->size }}">{{ $sizes->size }}</option>
                                            @endforeach
                                        </select>   
                                    </p>
                                    <img src="images/product-details/rating.png" alt="" />
                                    <span>
                                        <span id="getPrice">R {{ $productDetails->price }}</span>
                                        <label>Quantity:</label>
                                        <input name="quantity" type="text" value="1" />
                                        @if($total_stock>0)
                                            <button type="submit" class="btn btn-fefault cart" id="cartButton">
                                                <i class="fa fa-shopping-cart"></i>
                                                Add to cart
                                            </button>
                                        @endif  
                                    </span>
                                    <p><b>Availability: </b><span id="Availability"> @if($total_stock>0) In Stock @else Out Of Stock @endif</span></p>
                                    <p><b>Condition:</b> New</p>
            
                                    <a href=""><img src="images/product-details/share.png" class="share img-responsive"  alt="" /></a>
                                </div><!--/product-information-->
                            </form>
                        </div>
                    </div><!--/product-details-->
                    
                    <div class="category-tab shop-details-tab"><!--category-tab-->
                        <div class="col-sm-12">
                            <ul class="nav nav-tabs">
                                <li class="active"><a href="#description" data-toggle="tab">Description</a></li>
                                <li><a href="#care" data-toggle="tab">Material & Care</a></li>
                                <li><a href="#delivery" data-toggle="tab">Delivery Options</a></li>
                            </ul>
                        </div>
                        <div class="tab-content">
                            <div class="tab-pane fade" id="description" >
                                <div class="col-sm-12">
                                    <p>{{ $productDetails->description }}</p>
                                </div>  
                            </div>
                            
                            <div class="tab-pane fade" id="care" >
                                <div class="col-sm-12">
                                    <p>{{ $productDetails->care }}</p>
                                </div>
                            </div>
                            
                            <div class="tab-pane fade" id="delivery" >
                                <div class="col-sm-12">
                                    <p>100% Original Products <br>
                                    Cash on delivery might be available</p>
                                </div>
                            </div>
                    
                            
                        </div>
                    </div><!--/category-tab-->
                    
                    <div class="recommended_items"><!--recommended_items-->
                        <h2 class="title text-center">recommended items</h2>
                        
                        <div id="recommended-item-carousel" class="carousel slide" data-ride="carousel">
                            <div class="carousel-inner">
                                <?php $count=1; ?>
                                @foreach($relatedProducts->chunk(3) as $chunk)
                                <div <?php if($count==1){ ?> class="item active" <?php } else { ?> class="item" <?php } ?>> 
                                    @foreach($chunk as $item)
                                    <div class="col-sm-4">
                                        <div class="product-image-wrapper">
                                            <div class="single-products">
                                                <div class="productinfo text-center">
                                                    <img style="width:200px;" src="{{ asset('images/backend_images/product/small/'.$item->image) }}" alt=""  width="320" height="400"/>
                                                    <h2>R {{ $item->price }}</h2>
                                                    <p>{{ $item->product_name }}</p>
                                                    <a href="{{ url('/product/'.$item->id) }}"><button type="button" class="btn btn-default add-to-cart"><i class="fa fa-shopping-cart"></i>Add to cart</button></a>
                                                </div>
                                            </div>
                                        </div>
                                    </div>
                                    @endforeach
                                </div>
                                <?php $count++; ?>
                                @endforeach
                            </div>

Please or to participate in this conversation.