Laravel Output 1 result from hasmany relationship - laravel

I have a hasmany relationship on my model and I'm trying to output just the one result, i have a product category which can display only one product image.
I have two tables.
1 = Product
2 = ProductPhotos
I've tried outputting the one photo like
#foreach($products as $product)
<img src="{{ $product->photos->first() }}">
#endforeach
I have the following relationship setup in my product model
public function photos()
{
return $this->hasMany('App\ProductPhoto', 'product_id');
}
but this doesnt work.

You're just missing the parenthesis for the method. It should be:
$product->photos()->first();
Which will allow Eloquent to access the photos method in the Product model.

Related

Show many products from a category from many-to-many relationship in laravel

So I’m making a catalogue using Laravel 7.* and I have a problem.
I have many products and many categories. I have created a many-to-many relationship so a product can be in many categories.
Now, what I am trying to do is to show in a page each category with related products, but obviously I am doing something wrong.
Below you may see some code:
Product.php:
public function categories()
{
return $this->belongsToMany(Category::class);
}
Category.php:
public function product()
{
return $this->belongsToMany(Product::class);
}
Show.blade.php
#php
$products = \App\Product::with('categories')->find(1);
#endphp
#foreach ($products as $id)
{{ $id->name }}<br>
#endforeach
Any help please?
Fixed it.
I fetched categories in controller and send to view. Then for each category displayed each product.
Get all the categories and show products related to them.
#php
$categories= \App\Category::all();
#endphp
#foreach($categories as $category)
#foreach($category->product as $product)
{{$product->name}}
#endforeach
#endforeach
You need also Id of category that you want to show products related to it.
According To This answer
Try this:
$category_id = 1; // Desired Category Id
$products = \App\Product::whereHas('categories', function($query) use ($category_id) {
$query->where('category_id', $category_id);
})->paginate();
I also added pagination.

Getting a particular data from instance

I am trying to make a shopping cart in Laravel, and I am still a learner.
In the cart, I am trying to print details of products present in the cart, along with their quantity.
The details of several products of cart is present in $prod, while quantity is present in $cart. I am running a foreach to access each product of the cart, as well as its quantity.
In an explanatory way, I am trying to do this:
#foreach( $prod as $p )
<td>Quantity = {{ $cart[ "product_id" == $p->id]->quantity }}<td>
#endforeach
I am trying to match the $p->id, the details which I am printing, to the quantity in $cart as $cart has it under product_id attribute in table.
I am sorry if I am unable to explain the question the right way.
Thank you.
This solutions assumes you are using Eloquent Models, if you are not you should. On your Product.php model, define the relationship.
class Product extends Model {
public function cart()
{
// Laravel automatically know to look in carts table for an product_id column
return $this->belongsTo(Cart::class);
}
}
Now you have a relationship method for your cart, this is useful if you want to save it. For just loading it out of the database, if you access $product->cart it will automatically fetch the Cart.php model. So you can quite simply write.
#foreach( $prod as $p )
<td>Quantity = {{ $p->cart->quantity }}<td>
#endforeach

Merge two collections in Laravel and access it

Ok, so here is my problem : I have'nt found a proper solution to 'merge' (not sure if it is the right word for it) two collections in laravel. I'll show you my code, it'll explains itself.
So here is my crappy way-arround code, but I'm pretty sure there is a better way to do it :
Here is my controller :
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Product;
use App\ProductPhoto;
class ProductController extends Controller
{
public function index() {
$products = Product::all();
$photos = ProductPhoto::all();
return view('/products')->with([
'products' => $products,
'photos' => $photos
]);
}
}
and my view looks like this ;
#foreach($products as $product)
#foreach($photos as $photo)
#if($photo->product_id = $product->id)
<img src="/products/{{ $product->id }}/{{ $photo->filename }}">
#endif
#endforeach
#endforeach
But I'd like to have all the photos related to the product in the product collection. I'd like to have a simple view as :
#foreach($products as $product)
#foreach($product->photos as $photo)
<img src="/products/{{ $product->id }}/{{ $photo->filename }}"
#endforeach
#endforeach
Or another way simpler than that. I've been trying merge, but I don't think this is the one I need, I don't know. Or maybe the way I do it is the correct one, but I doubt it.
Thanks for reading !
I'd recommend using eloquent relationships for this. To do this you would want to create a relationship on the product class called photos. This would look something like this:
class Product extends Model
{
...
public function photos()
{
return $this->hasMany(ProductPhoto::class);
}
...
}
Once you have done this, you can update your controller as you no longer need to fetch the photos from the model. For performance, you could eager load the photos.
public function index() {
$products = Product::with('photos')->get();
return view('/products')->with([
'products' => $products
]);
}
Finally, you can update your view to use the photos relationship instead.
#foreach($products as $product)
#foreach($product->photos as $photo)
<img src="/products/{{ $product->id }}/{{ $photo->filename }}"
#endforeach
#endforeach
I hope that helps.
I don't usually like when people ignore the proposed example and tell you that there's a better way to do that... but there is a better way to do that:
for the Products Eloquent add a method called photos
Class Products extends Model{
...
public function photos(){
return $this->hasMany(Photos::class);
}
}
for the Photos Eloquent add a method called product
Class Photos extends Model{
...
public function product(){
return $this->belongsTo(Product::class);
}
}
now for the photos migration you need to add a column called product_id in case you're using this photos table only for products and not anything else like users.
if you want to be able to assign photos to multiple models like Users can have photos, then you need to consider using Morphs Polymorphic Relationships
when you want to add photos to the product you can then do
Product::find(1)->photos()->create(['filename'=>'....']);
That should add photos row assigned with the product.
Then in your view you can do something like:
#foreach(Products::all() as $_product)
<div>
{{$_product->title}
<div class="product_photos">
#foreach($_product->photos as $_photo)
<img .../>
#endforeach
</div>
</div>
#endforeach
I'm just showing you the correct way to achieve that instead of comparing photos with id and so on, your way will make it much slower.
Look up Laravel Relationships. That will take a bit of time like few minutes to convert your models to use Relationships but will save you days of coding later.

How call polymorphic for each item in loop

In Laravel 5.6 i have a polymorphic relationship .
I have many products in db and avatars for each product .
When i send products data to view i want to send avatar for every product .
I write a polymorphic relationship between avatars table and products table and i can access avatar of each product using this code easily :
$avatar = Product::find(id)->avatars()->first();
But when db result is NOT one product and is a array of products how i can access each avatar ?
If i have result like this how can i find avatar of each product in view file ? :
$products = Product::all();
return view('frontend/home')->with([
'products'=>$products,
]);
And in View i have something like this :
#foreach($products as $product)
<li>
#include('items.product')
</li>
#endforeach
You should be able to use with():
$products = Product::with('avatars')->get();
Then in your blade file you would have something like:
#foreach($products as $product)
<img src="{{ $product->avatars->first()->url }}" alt="" />
#endforeach

Laravel 5 Eloquent Relations

I have a prolem here with 2-level far relations between models. It's classic eCommerce website with expected structure where you have a product table, galleries and images. Product and Image has gallery_id so every gallery has potencialy many Images. This is my solution which doesn't work. Returns "Trying to get property 'images' of non-object".
VIEW Product.blade.php
<ul>
#foreach ($product->gallery->images as $image)
<li><img src="{{ asset($image->path) }}" alt="" data-image="{{ asset($image->path) }}"></li>
#endforeach
</ul>
MODEL Product.php
public function gallery()
{
return $this->belongsTo('App\Gallery');
}
MODEL Gallery.php
public function images()
{
return $this->hasMany('App\Image');
}
Why I can't access images from product view by $product->gallery->images?

Resources