Retrieving eloquent relationship with laravel - php

When I try to get the name of the Category from my product, I discovered I had to use a 'C' rather than a 'c' before it retrieved results. However when I try to get the Supplier name, the lowercase s works just fine. I was wondering what is causing this difference. Also if I dd($var), is the relations field expected to be empty. I assumed it would have something related to the relationships defined in my models.
Blade.php
<td>{{$product->Category->name}}</td>
<td>{{$product->salePrice}}</td>
<td>{{$product->stock}}</td>
<td>{{$product->supplier->company_name}}</td>
Product.php
public function category()
{
return $this->belongsTo('App\Category','category');
}
public function supplier()
{
return $this->belongsTo('App\Supplier','supplier_id');
}
Category.php
public function product()
{
return $this->hasMany('App\Product');
}
Supplier.php
public function product()
{
return $this->hasMany('App\Product');
}

You're missing a _id on your Product model:
public function category()
{
return $this->belongsTo('App\Category','category_id');
}
Or leave empty
public function category()
{
return $this->belongsTo('App\Category');
}
In your Controller
public function index()
{
$products = Product::all()->with('category');
return view('your_view', compact('products'));
}
If you dd the products
In your View you will se that the relation has been loaded because of the
Eager Loading
When accessing Eloquent relationships as properties, the relationship data is "lazy loaded". This means the relationship data is not actually loaded until you first access the property. However, Eloquent can "eager load" relationships at the time you query the parent model.
#foreach($products as $product)
<td>{{$product->category->name}}</td>
<td>{{$product->salePrice}}</td>
<td>{{$product->stock}}</td>
<td>{{$product->supplier->company_name}}</td>
#endforeach

Related

MorphMany relationship returning empty array in laravel 8

I'm trying to return the product data with image with Morph relationship
I can save the data, however when I'm retrieving it, the images field has empty value.
Product Model:
protected $fillable=['name', 'description'];
public function images(){
$this->belongsToMany(Category::class);
}
Image Model:
protected $fillable=['imagable_id', 'imagable_type', 'file_name'];
public function imagable(){
return $this->morphTo();
}
Product Controller: So this where I want to retrieve the product with image on it.
public function index(){
return Product::with('images')->get();
}
This controller return only the product data, but it has empty images array field.
Your product model definition for images() is pointing at the Category model and is a belongsToMany() vs. a morphMany(). You should also adjust the spelling of imageable to be correct.
Try adjusting your relationships like this
Product Model:
public function images(){
$this->morphMany(Image::class, 'imageable');
}
Image Model:
public function imageable(){
return $this->morphTo();
}

How to filter entries via hasMany relationship in Laravel

I'm trying write an website with Laravel (current version is 5.7) and I have 3 models as: Post, User and Fav. I'm using a simple form to add posts to "favs" table which has 3 columns as; id, user_id and post_id. And I want to list posts that user added favorites bu I can't use "hasMany" method properly.
I can use variables like; $post->user->name but I can't figure it out how to use relationship with "favs" table.
Post Model
public function user() {
return $this->belongsTo('App\User');
}
public function favs() {
return $this->hasMany('App\Fav');
}
Fav Model
public function users() {
return $this->hasMany('App\User');
}
public function posts() {
return $this->hasMany('App\Post', 'post_id', 'id');
}
User Model
public function posts() {
return $this->hasMany('App\Post');
}
public function favs() {
return $this->hasMany('App\Fav');
}
Controller
public function user($id){
$favs = Fav::orderBy('post_id', 'desc')->get();
$user = User::find($id);
$posts = Post::orderBy('id', 'desc')->where('user_id', $id)->where('status', '4')->paginate(10);
return view('front.user')->with('user', $user)->with('posts', $posts)->with('favs', $favs);
}
The Fav model only has one User and Post each, so you need to use belongsTo() instead of hasMany and change the method names to singular. You can also remove the additional parameters in post() since they're the default values.
public function user() {
return $this->belongsTo('App\User');
}
public function post() {
return $this->belongsTo('App\Post');
}
Loading all Posts that a user has favorited:
$user->favs()->with('post')->get();
The with() method is used to eager load the relationship.
Now you can loop through the Favs:
#foreach($favs as $fav)
{{ $fav->post->name }}
#endforeach
I think you can change these two lines of your code to
$posts = Post::orderBy('id', 'desc')->where('user_id', $id)->where('status', '4')->paginate(10);
return view('front.user')->with('user', $user)->with('posts', $posts)->with('favs', $favs);
to
$posts = Post::where('user_id', $id)->where('status', '4')->latest()->paginate(10);
return view('front.user', compact('user', 'posts', 'favs'));
And for retrieving favorite posts of an user,
if you will change the fav table to make it a pivot table only to handle a many to many relationships between Post and User, you can get it as $user->posts, for a separate model, I think you can consider something like $user->favs and in view
In Fav model
public function user() {
return $this->belongsTo('App\User');
}
public function post() {
return $this->belongsTo('App\Post');
}
and in view
#foreach ( $user->favs as $fav )
{{ $fav->post->id }}
#endforeach
If an User, per example, have many Favs you need to use a Iteration Block, like foreach.
Example:
foreach($user->favs as $fav) {
dd($fav) // do something
}
Ps.: Be careful not to confuse hasMany and belongsToMany.

getRouteByKeyName another model laravel

I have two models:
Categories
CategoriesTranslations
In model categories I writed:
public function getRouteKeyName(){
return 'alias';
}
Column alias belogns model CategoriesTranslations.
How I can return alias from model CategoriesTranslations?
My code is not working.
I tryed:
Add getRouteKeyName on CategoriesTranslations:
public function getRouteKeyName(){
return 'alias';
}
And in Categories add:
public function categoryTranslations() {
return $this->hasOne(CategoriesTranslations::class);
}
public function getRouteKeyName() {
return $this->categoryTranslations->getRouteKeyName();
}
I get error Call to a member function getRouteKeyName() on null When want show category by getRouteKeyName. How fix it?
You must use relationships between Categories and CategoriesTranslations.
In your Categories model:
public function categoriesTranslations()
{
return $this->hasMany(CategoriesTranslations::class);
}
public function getRouteKeyName()
{
$this->categoryTranslations->where('locale', Auth::user()->locale)->first()->getRouteKeyName();
}
Now you can call getRouteKeyName() from any instance of the Categories model and it will pull it from the CategoriesTranslations table.
** The potential fix here was adding in the where() statement and the first() method. Change the Auth::user()->locale to wherever you are storing which locale to use.

Laravel: Cannot get parent of a category

I am working on a classified ads platform and i am having a problem with a relation. Although i think i've set up everything right there is still this issue.
The scenario is this:
I have a model Category (App\Category) with the folowing relations to form the subcategories
class Category extends Model
{
public function parent() {
return $this->belongsTo('App\Category', 'parent_id');
}
public function children() {
return $this->hasMany('App\Category', 'parent_id');
}
public function adverts() {
return $this->hasMany('App\Advert');
}
}
I also have a model Advert (App\Advert) with the following relations
class Advert extends Model
{
public function category() {
return $this->belongsTo('App\Category');
}
public function user() {
return $this->belongsTo('App\User');
}
}
And finally I have a model User (App\Advert) with the following relations
class User extends Authenticatable
{
public function adverts() {
return $this->hasMany('App\Advert');
}
}
I am collecting the adverts in a collection within a controller like this
$adverts = $user->adverts()->with('category')->with('category.parent')->get();
The problem i am facing is when i try to output the adverts and the category they belong along with the corresponding subcategory i am experiencing this issue
Trying to get property of non-object (View:
..\resources\views\user\profile.blade.php)
On the following line
$ad->category->parent->name . ' / ' . $ad->category->name
When i dd the collection i can see all the adverts and the relations together with the category and the subcategory ... but when i try to output it like this i got this error Trying to get property of non-object
Help anyone?
Thanks
I am not sure if this helps anything, but I am posting it as an answer to make the code more readable, thats all. Not expecting any credits ;)
In one of my models I set up the child / parents relationships like this:
/**
* Get the Categories associated with the parent's `id`
*/
public function children()
{
return $this->hasMany('App\Category', 'parent_id', 'id');
}
/**
* Get the parent associated with the Category`s parent_id`
*/
public function parent()
{
return $this->belongsTo('App\Category');
}

How to get third relation in laravel

I have the following models: User, Device, Product.
User
public function devices()
{
return $this->hasMany('App\Device');
}
Device
public function user()
{
return $this->BelongsTo('App\User');
}
public function reading()
{
return $this->hasMany('App\Reading', 'device_id', 'part_id');
}
public function product()
{
return $this->hasOne('App\Product');
}
Product
public function device()
{
return $this->belongsTo('App\Device');
}
The following query pulls my users and all their devices, but inside that collection is not the relation from device to product.
$deviceSingles = User::with('devices')->get();
This query gets me all the products with all devices assigned to it
$deviceSinglesTwo = Product::with('device')->get();
How do I get that third relation, attached to my initial query so i can do this
$deviceSingles->device->product->title
Use nested eager loading.
To eager load nested relationships, you may use "dot" syntax.
User::with('devices.product')->get()

Categories