Symfony\Component\Debug\Exception\FatalThrowableError (E_ERROR) Class 'Cart' not found - php

When calling a delete function on a product I get above error. The delete function works fine if i comment out the line where i detach the pivot table, however when deleting a product i would like to delete all entries in the pivot table as well. Does anyone know why this is happening?
The database has been migrated and seeded succesfully.
Pivot Table Migration:
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateOrderProductTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('order_product', function (Blueprint $table) {
$table->integer('order_id');
$table->integer('product_id');
$table->float('price');
$table->integer('amount');
$table->primary(array('order_id', 'product_id'));
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('orders_products');
}
}
Product Model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Product extends Model
{
protected $fillable = ['name', 'price', 'stock', 'short_description', 'long_description'];
public function orders() {
return $this->belongsToMany('App\Order', 'order_product', 'product_id', 'order_id');
}
public function carts() {
return $this->belongsToMany('App\Cart', 'cart_product', 'product_id', 'cart_id');
}
}
Delete Function:
public function destroy($id)
{
if ($this->validateID($id)) {
$product = Product::find($id);
//$product->carts()->detach(); --THE PROBLEMATIC LINE
Product::destroy($id);
}
Session::flash('success', $product->name.' has been succesfully deleted.');
return redirect()->to('/products');
}

You did not provide a full namespace in your belongsToMany relationship.
Probably something like that (unless you have subfolders for models):
public function orders() {
return $this->belongsToMany('App\Order', 'order_product', 'product_id', 'order_id');
}
public function carts() {
return $this->belongsToMany('App\Cart', 'cart_product', 'product_id', 'cart_id');
}
Also, I would recommend adding this to your pivot migration:
Schema::create('order_product', function (Blueprint $table) {
// Also, you would need to make `order_id` and `product_id` unsigned,
// assuming your other `id` columns are `autoincrement` (which are unsigned by default)
$table->integer('order_id')->unsigned();
$table->integer('product_id')->unsigned();
$table->float('price');
$table->integer('amount');
$table->primary(array('order_id', 'product_id'));
$table->timestamps();
// Adds foreign key to orders
$table->foreign('order_id')
->references('id')
->on('orders')
// Automatically deletes the pivot, when related order is deleted
->onDelete('cascade');
// Adds foreign key to products
$table->foreign('product_id')
->references('id')
->on('products')
// Automatically deletes the pivot, when related cart is deleted
->onDelete('cascade');
});
Also your table in down() part of migration mismatches the actual table name in the up() part.

Related

Laravel Categories

I'm learning php with laravel and trying to implement categories and subcategories for multiple on my project.
For Example: I have Books, Mobiles in my project
Books has its own categories and subcategories. Same goes for Mobile.
I have added another table with relation
Schema::create('category_product', function (Blueprint $table) {
$table->increments('id');
$table->integer('product_id')->unsigned();
$table->integer('category_id')->unsigned();
$table->unique(array('product_id', 'category_id'));
// foreign key constraints are optional (but pretty useful, especially with cascade delete
$table->foreign('product_id')->references('id')->on('products')->onDelete('cascade');
$table->foreign('category_id')->references('id')->on('categories')->onDelete('cascade');
});
Category Database Schema
Schema::create('categories', function (Blueprint $table) {
$table->increments('id');
$table->integer('parent_id')->nullable()->index();
$table->string('title')->unique();
$table->string('slug')->unique();
$table->string('description')->nullable();
$table->string('keywords')->nullable();
$table->timestamps();
});
category.php (Model)
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use Cviebrock\EloquentSluggable\Sluggable;
class Category extends Model
{
use Sluggable;
/**
* Return the sluggable configuration array for this model.
*
* #return array
*/
public function sluggable()
{
return [
'slug' => [
'source' => 'title'
]
];
}
/**
* The database table used by the model.
*
* #var string
*/
protected $table = 'categories';
/**
* Attributes that should be mass-assignable.
*
* #var array
*/
protected $fillable = [
'parent_id', 'title', 'description', 'slug'
];
public function parent()
{
return $this->belongsTo('Category', 'parent_id');
}
public function children()
{
return $this->hasMany('Category', 'parent_id');
}
public function categoryProduct(){
return $this->belongsToMany('CategoryProduct');
}
public function product(){
return $this->belongsToMany('Product');
}
}
Am i doing the right way as i didn't find a proper tutorial for this kind of approach. Do i need to create a CategoryProduct.php model and reference
public function categories(){
return $this->belongsToMany('Category');
}
public function products(){
return $this->belongsToMany('Product');
}
No, you don't need to create a model for a pivot table. Eloquent has many methods to make working with pivot tables a breeze. In your case you don't need a model.
But sometimes, when you're working with pivot table additional columns a lot it's a good idea to create a model for a pivot table.

laravel eloquent relation one to many returns null

The product data always return null when i get the incoming_goods data (belongsTo).
Here is my Product Model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Product extends Model
{
use SoftDeletes;
protected $guarded = [
'id', 'created_at', 'updated_at', 'deleted_at',
];
public function transaction_details()
{
return $this->hasMany('App\Transaction_detail');
}
public function incoming_goods()
{
return $this->hasMany('App\Incoming_good');
}
}
Here is my Incoming_good Model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Incoming_good extends Model
{
protected $guarded = [
'id', 'created_at', 'updated_at',
];
public function product()
{
return $this->belongsTo('App\Product');
}
}
And here is my migration of that two table:
products table Migration:
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateProductsTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('products', function (Blueprint $table) {
$table->increments('id');
$table->string('name', 50);
$table->integer('price');
$table->integer('stock')->nullable();
$table->integer('available');
$table->string('image1', 190)->nullable();
$table->string('image2', 190)->nullable();
$table->string('image3', 190)->nullable();
$table->string('image4', 190)->nullable();
$table->string('image5', 190)->nullable();
$table->timestamps();
$table->softDeletes();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('products');
}
}
incoming_goods migration:
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateTableIncomingGoods extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('incoming_goods', function (Blueprint $table) {
$table->increments('id');
$table->integer('product_id');
$table->integer('stock');
$table->text('note')->nullable();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('incoming_goods');
}
}
Here is my code to show incomong_goods data and product (relation belongsTo):
$data = Incoming_good::select('id', 'stock', 'note', 'created_at')->with('product')->get();
I've try to use alies, but still it return the product data null. Hope you can help me :)
In order to match up the eager loaded Products with the Incoming_goods, Laravel needs the foreign key to be selected. Since you did not include the foreign key (product_id) in the select list, Laravel can't match up the related records after retrieving them. So, all your product relationships will be empty. Add in the foreign key to the select list, and you should be good.
$data = Incoming_good::select('id', 'product_id', 'stock', 'note', 'created_at')
->with('product')
->get();

Eloquent relationships: cloumn doesn't exist

I'm new to Laravel and am having a bit of a hard time cracking how relationships work. I'm building a simple e-commerce application, where each user has some orders, and order has one or many sub-orders, and each sub-order is linked to only one item (please don't comment on my scheme yet; for now I just need to figure out Eloquent and will be doing refactoring later :) ).
Following are my models:
class Order extends Model
{
//timestamp
protected $created_at;
public function sub_orders() {
return $this->hasMany('App\SubOrder');
}
public function user() {
return $this->belongsTo('App\User');
}
}
class SubOrder extends Model
{
protected $fillable = array('delivery_date', 'quantity', 'total_price', 'delivery_status');
public function item() {
return $this->hasOne('App\Item');
}
public function order() {
return $this->belongsTo('App\Order');
}
}
class Item extends Model
{
//note - slug is kind of categorization and is common to many items
protected $fillable = array('sku', 'name', 'slug', 'unit_price');
}
And here are the migrations:
class CreateOrdersTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('orders', function (Blueprint $table) {
$table->increments('id');
$table->timestamp('created_at');
//foreign keys
$table->unsignedInteger('user_id')->after('id');
$table->foreign('user_id')->references('id')->on('users') ->onDelete('cascade');
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('orders');
}
}
class CreateSubOrdersTable extends Migration
{
public function up()
{
Schema::create('sub_orders', function (Blueprint $table) {
$table->increments('id');
$table->date('delivery_date');
$table->decimal('quantity', 5, 2);
$table->decimal('total_price', 7, 2);
$table->enum('delivery_status', ['pending_from_farmer', 'ready_for_customer', 'out_for_delivery', 'delivered']);
//foreign keys
$table->unsignedInteger('order_id')->after('id');
$table->foreign('order_id')->references('id')->on('orders') ->onDelete('cascade');
$table->unsignedInteger('item_id')->after('order_id');
$table->foreign('item_id')->references('id')->on('items') ->onDelete('cascade');
});
}
public function down()
{
Schema::dropIfExists('sub_orders');
}
}
class CreateItemsTable extends Migration
{
public function up()
{
Schema::create('items', function (Blueprint $table) {
$table->increments('id');
$table->string('sku')->unique();
$table->string('name');
$table->string('slug');
$table->decimal('unit_price', 5, 2);
});
}
public function down()
{
Schema::dropIfExists('items');
}
}
The problematic expression is why I write App\Order::all()[0]->sub_orders[0]->item in my web.php and get the following error:
SQLSTATE[42703]: Undefined column: 7 ERROR: column items.sub_order_id does not exist
LINE 1: select * from "items" where "items"."sub_order_id" = $1 and ...
^ (SQL: select * from "items" where "items"."sub_order_id" = 1 and "items"."sub_order_id" is not null limit 1)
I don't understand why it's looking for sub_order_id in the items table. And what's the right way to go about doing it?
Overall: define the 1-to-1 relationship using hasOne or belongsTo will affect the target table where Laravel find the foreign key. hasOne assume there is a my_model_id in target table.And belongsTo assume there is a target_model_id in my table.
class SubOrder extends Model
{
public function item() {
return $this->hasOne('App\Item', 'id', 'item_id');
}
}
or
class SubOrder extends Model
{
public function item() {
return $this-> belongsTo('App\Item');
}
}
According to Laravel Doc
class User extends Model
{
/**
* Get the phone record associated with the user.
*/
public function phone()
{
return $this->hasOne('App\Phone');
}
}
Eloquent determines the foreign key of the relationship based on the model name. In the above case, the Phone model is automatically assumed to have a user_id foreign key. If you wish to override this convention, you may pass a second argument to the hasOne method:
$this->hasOne('App\Phone', 'foreign_key', 'local_key');
Or Defining The Inverse Of The Relationship
class Phone extends Model
{
/**
* Get the user that owns the phone.
*/
public function user()
{
return $this->belongsTo('App\User');
}
}
In the example above, Eloquent will try to match the user_id from the Phone model to an id on the User model.
Your SubOrder item has relationship of type OneToOne (hasOne is bidirectional) with an Item.
So Eloquent expects to have sub_order_id in the items table.
So the solution is to define the inverse of this relationship (belongsTo) in the Item model

Eloquent eager loading doesn't work with my naming convention

I have been stuck for most of the day getting an empty array any time I eager loaded product images while requesting products in my controller in Laravel.
public function ProductImages() {
return $this->hasMany('App\ProductImage', 'product_id'); // this matches the Eloquent model
}
I changed my code to make the FK 'test' and suddenly it has started returning the appropriate data I want back. I put the FK back to product_id but again am back to an empty array. Below are My product Model ProductImages Model and the migrations for both with the call Im making in the controlelr
Product Model
class Product extends Model
{
protected $fillable = array('name', 'url_name', 'sku', 'description', 'short_description', 'enabled', 'track_inventory', 'stock_level', 'allow_backorder', 'updated_user_id' );
//protected $hidden = array('id');
// LINK THIS MODEL TO OUR DATABASE TABLE ---------------------------------
// Database table is not called my_products
protected $table = 'products';
// each product HAS many product images
public function ProductImages() {
return $this->hasMany('App\ProductImage', 'productId'); // this matches the Eloquent model
}
}
Product Images Model
class ProductImage extends Model
{
protected $fillable = array('name', 'description', 'path', 'sort_order', 'product_id');
// DEFINE RELATIONSHIPS --------------------------------------------------
// each attribute HAS one product
public function Product() {
return $this->belongsTo('App\Product', 'id'); // this matches the Eloquent model
}
}
Product Migration
class CreateProductsTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('products', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('url');
$table->string('sku');
$table->string('description');
$table->string('short_description');
$table->integer('enabled');
$table->integer('track_inventory');
$table->integer('stock_level');
$table->integer('allow_backorder');
$table->dateTime('updated_user_id');
$table->timestamps();
});
}
}
Product Images Migration
class CreateProductImagesTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('product_images', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('description');
$table->string('path');
$table->integer('sort_order');
$table->integer('product_id')->unsigned();
$table->foreign('product_id')->references('id')->on('products');
$table->timestamps();
});
}
}
Product Controller Snippet
public function index()
{
//
$Products = Product::with('ProductImages','productTypes')->get();
//dd($Products);
return response()->json( $Products, 200);
}
If you could help me understand why this strange behavior is happening i would be very grateful.

Laravel belongsTo throwing undefined function App/BelongsTo() exception

I have a comments table and user table with the relationship: user->hasMany('comments') and comment->belongsTo('user'). For some reason with which eludes me, I keep getting this
FatalErrorException in Comment.php line 22: Call to undefined function App\belongsTo()
My other models have no issue whatsoever with the HasMany relations, however, the comments model has a problem with every single thing i try (even if i use HasMany just to see if it will have a different error).
Here is the Comment model.
use Illuminate\Database\Eloquent\Model;
class Comment extends Model {
protected $table = 'comments';
protected $fillable = [
'anime_id',
'user_id',
'user_comment'
];
public function postedOnAnime($query)
{
$query->where('anime_id', '=', $this.id);
}
public function user()
{
return $this.belongsTo('App\User', 'user_id', 'id');
}
public function anime()
{
return $this.belongsTo('App\Anime');
}
}
Here is the Users table:
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateUsersTable extends Migration {
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('users', function(Blueprint $table)
{
$table->increments('id');
$table->integer('role');
$table->string('name')->unique();
$table->string('email')->unique();
$table->string('password', 60);
$table->rememberToken();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::drop('users');
}
}
Here is the Comments table
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateCommentsTable extends Migration {
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('comments', function(Blueprint $table)
{
$table->increments('id');
$table->integer('user_id')->unsigned();
$table->integer('anime_id')->unsigned();
$table->text('user_comment');
$table->timestamps();
$table->foreign('user_id')
->references('id')
->on('users')
->onDelete('cascade');
$table->foreign('anime_id')
->references('id')
->on('animes')
->onDelete('cascade');
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::drop('comments');
}
}
Finally, when I call $comment->user() it fails with the error. Does anyone know where this error comes from?
Thanks.
Well, this error occurred because I had '.' in place of '->'. I couldn't figure out why it was always throwing the exact same error regardless if I did $this.belongsTo('App\User'); or $this.hasMany('App\User'); or even $this.thecakeisalie('App\User'); until I sat staring at the text between my many models yet again. Then, lo and behold, its another dumb, tiny and really hard to locate mistake of mine(as it usually is).
return $this.belongsTo('App\User', 'user_id', 'id');
to
return $this->belongsTo('App\User');
I think this is a common mistake coming from other languages where . is used to access properties. In PHP, it should be ->.
$this.belongsTo('...')
should be rewritten as
$this->belongsTo('...')

Categories