i am trying to get the name using a relationship - laravel

here what I am trying to get the name of the category by using a relationship
here so far what I have done is I have defined a relationship in my product model as such
Public function category()
{
return $this->belongsto(Category::class);
}
I have also stored the field category id
in my products table
Schema::create('products', function (Blueprint $table) {
$table->increments('id');
$table->integer('Category_id');
$table->string('name');
$table->string('code');
$table->string('color');
$table->string('description');
$table->double('price');
$table->integer('quantity');
$table->string('image');
$table->timestamps();
});
also I have defined a relationship in my Category model such as
public function product()
{
return $this->hasmany(Product::class);
}
ALSO I HAVE DEFINED Relationship IN
PRODUCT AS
Public function category()
{
return $this->belongsto(Category::class);
}
in my view I am trying to get the name of the category
#foreach($products as $pro)
<tr>
<td><img src="{{asset('uploads/maj/'.$pro->image)}}" class="img-circle" alt="User Image" width="50" height="50"> </td>
<td>{{$pro->category->name}}</td>
<td>{{$pro->name}}</td>
<td>{{$pro->code}}</td>
<td>{{$pro->color}}</td>
<td>{{$pro->description}}</td>
<td>{{$pro->price}}</td>
<td>{{$pro->quantity}}</td>
I am receiving the error
Trying to get property 'name' of non-object
how can I get the name of the category ??
I am trying to get it like this but this is giving error
{{$pro->category->name}}
the category table row
Schema::create('categories', function (Blueprint $table) {
$table->increments('id');
$table->String('Parent_id');
$table->string('name');
$table->string('status');
$table->timestamps();
});
my laravel version is 7 thanks

Maybe one or more product doesn't have category or category_id is wrong.
you can use condition to check if category is not exist:
{{$pro->category ? $pro->category->name : "no category"}}
or can simply using null coalescing operator:
{{$pro->category->name ?? "no category"}}
if category is required you should prevent it by add table relation/foreign.

try this
Schema::create('products', function (Blueprint $table) {
$table->increments('id');
$table->foreignId('category_id')->nullable()->constrained()->onDelete('cascade');
$table->string('name');
$table->string('code');
$table->string('color');
$table->string('description');
$table->double('price');
$table->integer('quantity');
$table->string('image');
$table->timestamps();
});
in model Product
public function category(){
return $this->belongsTo(Category::class,'category_id','id');
}
thin call products
$products = product::orderBy('created_at','asc')->with('category')->get();
you can chick if has relationship or not
#if(! empty($pro->category)) {{ $pro->category->name }} #else <span>no category</span> #endif

You should try like this way :
(!empty($pro->category)) ? $pro->category->name : 'No category found'

I think You should define foreign key properly because your category_id not follow the coding standard. if you Category Model are in App directory you can use pass namespace like this
Public function category()
{
return $this->belongsto('App\Category','Category_id','id');
}
other wise :
Public function category()
{
return $this->belongsto('App\Models\Category','Category_id','id');
}

Related

ErrorException Trying to get property 'name' of non-object in Hasmany relationship

Hello I am trying to access the Brand of a Vehicle through a HasMany relationship and receive the Property error, how can I fix it?
Migrations
Vehicles
Schema::create('vehicles', function (Blueprint $table) {
$table->id();
$table->integer('year');
$table->string('color');
$table->timestamps();
});
Brands
Schema::create('brands', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->foreignId('vehicles_id')->constrained()->onUpdate('cascade')->onDelete('cascade');
$table->timestamps();
});
Models
Vehicles
public function Brands()
{
return $this->BelongsTo(Brand::class,'vehicles_id');
}
Brand
public function Vehicles()
{
return $this->hasMany(Vehicle::class,'vehicles_id');
}
Method
$V = Vehicle::find($id);
dd($V->Brands->name);
You have relationship the incorrect way.
In your current code One brand (BMW) can be attached only to one vehicle. But in reality it is the other way. Vehicle belongs to one Brand, but one Brand can have multiple Vehicles.
Just flip the relationship
Schema::create('vehicles', function (Blueprint $table) {
$table->id();
$table->integer('year');
$table->string('color');
$table->foreignId('brand_id')->constrained()->onUpdate('cascade')->onDelete('cascade');;
$table->timestamps();
});
Foreign key should be in vehicles table
Vehicle belongs to Brand
// Models/Vehicle.php
// singular, because vehicle belong only to one Brand
public function brand()
{
return $this->belongsTo(Brand::class);
}
Brand has many vehicles
// Models/Brand.php
// plural because one Brand has many vehicles
public function vehicles()
{
return $this->hasMany(Vehicle::class,'vehicles_id');
}
Then in you controller:
$vehicle = Vehicle::with('brand')->find($id);
dd($vehicle->brand->name);

Retriving All Polymorphic Relations in Laravel

I've created polymorphic relations in my project. when i want to retrieve them like below
return view('category.index')->with('categories', Category::all()) ;
It returns the relations when i dd() them. However when I want to access the relation in view
when i call it in view it gives me the following result
{"id":1,"image":"abc\/abc.jpg","imageable_id":6,"imageable_type":"App\\Category","created_at":"2020-07-24T13:37:29.000000Z","updated_at":"2020-07-24T13:37:29.000000Z"}
but when i want to access the id or image index it says
Trying to get property 'id' of non-object (View:
D:\WaheedSindhani\Projects\Menu\menu_proj\resources\
views\category\index.blade.php)
i am not picking it up what is happening here
#if(isset($categories))
#foreach($categories as $category)
<tr>
<th scope="row">{{$loop->index+1}}</th>
<td>{{$category->name}}</td>
<td>{{$category->images->image}}</td>
</tr>
#endforeach
#endif
It says no attribute named image found.
Migration are as below
Images Table
public function up()
{
Schema::create('images', function (Blueprint $table) {
$table->id();
$table->string('image');
$table->unsignedInteger('imageable_id');
$table->string('imageable_type');
$table->timestamps();
});
}
Menus Table
public function up()
{
Schema::create('menus', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->boolean('visible');
$table->integer('priority');
$table->timestamps();
});
}
Categories Table
public function up()
{
Schema::create('categories', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->boolean('visibility');
$table->integer('priority');
$table->timestamps();
});
}
Models are as follow
class Menu extends Model
{
public function images()
{
return $this->morphMany( 'App\Image', 'imageable');
}
}
class Image extends Model
{
protected $guarded = [];
public function imageable(){
return $this->morphTo();
}
}
class Category extends Model
{
protected $guarded = [];
public function images()
{
return $this->morphMany(Image::class, 'imageable');
}
}
your problem occurs because the category->images is a Collection of images, not a single image. Because your relation is one to many, not one to one relationship so the soultion would be to loop over the images using a each loop and then do your work there.
that is why you are getting the error that you are trying to access a prop on a non-object.
#if(isset($categories))
#foreach($categories as $category)
<tr>
<th scope="row">{{$loop->index+1}}</th>
<td>{{$category->name}}</td>
#foreach($category->images as $image)
<td>{$image->name}</td>
#endforeach
</tr>
#endforeach
#endif
and this concept is true for every relationship that has a Many in them, hasMany, belongsToMany, etc...

How to return name of table of grade when save like json?

I have two tables, users and grades.
users table
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name');
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->string('first_name')->nullable();
$table->string('last_name')->nullable();
$table->string('grade_id')->nullable();
}
}
grades table
public function up()
{
Schema::create('grades', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name');
$table->timestamps();
});
}
I save id of grade with json_encode,
I save in field like this
$user->grade_id = json_encode($request->input('grade_id'));
I want to return the grade name but I did not solve my problem
Controller
public function index()
{
$grades = Grade::all();
return view('index', compact('grades');
}
User.php
public function grade()
{
return $this->belongsTo(Grade::class);
}
index.blade.php
#if(isset(auth()->user()->grade_id) && !empty(auth()->user()->grade_id))
<?php
$grade = json_decode(auth()->user()->grade->name, true);
#foreach($grade as $key=>$item)
<li>
<div class="grade">{{ $grade[$key] }}</div>
</li>
#endforeach
?>
#endif
I get this errpr
Trying to get property of non-object
Bad answer
You save an array of ids in the users table. Then when you do $grade = json_decode(auth()->user()->grade->name) you get something you don't want to have. Indeed, the value of auth()->user()->grade is ["8", "8"], this is not a grade model. Now you should understand why this $grade = json_decode(auth()->user()->grade->name) fail: you're trying to get name property of a non object (as user()->grade is just an array).
To solve it badly (read the next part of my answer) you can just do this in your controller (you shouldn't do any <?php ?> in your view files):
public function index()
{
$grades_ids = json_decode(auth()->user()->grade); // ["8", "8"]
$grades = Grade::whereIn('id', $grades_ids)->get(); // Eloquent collection
return view('index', compact('grades');
}
And use it in your view:
#if($grades->count())
<ul>
#foreach($grades as $grade)
<li>
<div class="grade">{{ $grade->id }}</div>
</li>
#endforeach
</ul>
#endif
Good answer
Here you have a typical many to many relationships. A grade can have multiple users, and a user can have multiple grades. Then you should think of using a pivot table rather than a encoding several grade_id in json.
Create a users table:
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name');
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->string('first_name')->nullable();
$table->string('last_name')->nullable();
}
}
Then you create your grades table:
public function up()
{
Schema::create('grades', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name');
$table->timestamps();
});
}
Then you create the new user_grade_table:
public function up()
{
Schema::create('user_grade', function (Blueprint $table) {
$table->primary(['user_id', 'grade_id']);
$table->unsignedBigInteger('user_id');
$table->unsignedBigInteger('grade_id');
$table->timestamps();
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$table->foreign('grade_id')->references('id')->on('users')->onDelete('cascade');
});
}
public function down()
{
Schema::table('user_grade', function (Blueprint $table) {
$table->dropPrimary('user_grade_user_id_grade_id_primary');
$table->dropForeign('user_grade_user_id_foreign');
$table->dropForeign('user_grade_grade_id_foreign');
});
Schema::dropIfExists('user_grade');
}
Don't forget to run the migrations. When this is done, you have to update your models, adding the belongs to many on both models.
User model
public function grades()
{
return $this->belongsToMany(Grade::class, 'user_grade', 'user_id', 'grade_id');
}
Same for grade model:
public function users()
{
return $this->belongsToMany(User::class, 'user_grade', 'grade_id', 'user_id');
}
Finally you can use it in your blade file:
#if($grades = auth()->user()->grades)
<ul>
#foreach($grades as $grade)
<li>
<div class="grade">{{ $grade->name }}</div>
</li>
#endforeach
</ul>
#endif

Laravel Polymorphic HasOne ,two different categories model to the same item

I'm trying to use two different Category model to the same items table.
I'v got 3 models
SystemCategory
Schema::create('system_categories', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name');
$table->timestamps();
});
UserCategory
Schema::create('user_categories', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name');
$table->integer('user_id');
$table->timestamps();
});
Item
Schema::create('items', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name');
$table->integer('categoryable_id');
$table->string('categoryable_type');
$table->timestamps();
});
Item category could be either from system_categories or user_categories table
I saw some Polymorphic relations but its about how two different models can belongs to one category, not about how model can belongs to two different category models
Thanks.
It can be done, first thing your schema looks ok but you want to set catagoryable_id to a bigInteger to match the id columns of the 2 category tables.
Then you would set your models up
class Item extends Model
{
public function categoryable()
{
return $this->morphTo();
}
}
class SystemCategory extends Model
{
public function items()
{
return $this->morphMany('App\Item', 'categoryable');
}
}
class UserCategory extends Model
{
public function items()
{
return $this->morphMany('App\Item', 'categoryable');
}
}
Obviously this is presuming your models are in the App namespace

How to solved in Laravel relations null value

Im tru to use to last version of laravel and i have small problem with Laravel relationship One to Many
Im try to connect products with categories
This is my code of Product model
public function categories()
{
return $this->belongsTo('App\Category');
}
this is my code of Category model
public function products()
{
return $this->hasMany('App\Product');
}
This is my code in controller
$products = Product::with('categories')->get();
dd($products);
this is my code from migration files
Schema::create('products', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('category_id');
$table->string('name')->unique();
$table->string('slug')->unique();
$table->string('keywords')->nullable();
$table->string('price');
$table->text('description')->nullable();
$table->text('image')->nullable();
$table->timestamps();
$table->foreign('category_id')->references('id')->on('categories');
});
Schema::create('categories', function (Blueprint $table) {
$table->id();
$table->string('name')->unique();
$table->string('slug')->unique();
$table->string('keywords')->nullable();
$table->timestamps();
});[![enter image description here][1]][1]
If someone know how to solved this problem I'll be very grateful
Firstly relation comes with eager loading.
Please update your codes according to single usage
In Product Model
public function category()
{
return $this->belongsTo('App\Category');
}
In Controller
$products = Product::with('category')->get();
dd($products[0]->category);
You are telling relationships name is categories, so laravel belongsTo will look categories_id instead category_id.
You can rename your relationships name as category() or
give your relationships foreign key to laravel like this;
return $this->belongsTo('App\Category', 'category_id', 'id');

Resources