Adding product to wishlist laravel - php

I'm creating a functionality which allows the user to add product in wishlist, but I'm getting an error Trying to get property of non-object when I click the (whishlist blade), the error comes from this line <h4>USD {{$wishlist->product->price }}</h4> if I remove the $product it displays no price how do i fix this?
Wishlist Controller
public function index()
{
$user = Auth::user();
$wishlists = Wishlist::where("user_id", "=", $user->id)->orderby('id', 'desc')->paginate(10);
return view('wishlist', compact('user', 'wishlists'));
}
Blade
#if (Auth::user()->wishlist->count() )
#foreach($wishlists as $wishlist)
<h2>USD {{$wishlist->product->price }}</h2>
<h4>USD {{$wishlist->product->name }}</h4>
#endforeach
#endif
Wishlist.php
class Wishlist extends Model
{
protected $table = "wishlist";
protected $fillable=['product_id','user_id'];
public function user(){
return $this->belongsTo(User::class);
}
public function product(){
return $this->belongsTo(Product::class);
}
}
User.php
public function wishlist(){
return $this->hasMany(Wishlist::class);
}
Product.php
public function wishlist(){
return $this->hasMany(Wishlist::class);
}

You should first change how you check the count of wishlist, since it runs a heavy query that recovers all wishlists then count them. And also remove the $ in $product as #lucasArbex suggested
#if ($wishlists->count() )
#foreach($wishlists as $wishlist)
<h2>USD {{$wishlist->product->price }}</h2>
<h4>USD {{$wishlist->product->name }}</h4>
#endforeach
#endif
Also change your controller and use the relation on your user
public function index()
{
$user = Auth::user();
$wishlists = $user->wishlist()->with('product')
->orderby('id', 'desc')
->paginate(10);
return view('wishlist', compact('user', 'wishlists'));
}

Firstly, you should access the product relation like so (removing $):
$wishlist->product->price
Secondly, you should eager load the wishlist's product using the ::with() query builder:
public function index()
{
$user = Auth::user();
$wishlists = Wishlist::with('product')
->where('user_id', $user->id)
->orderby('id', 'desc')
->paginate(10);
return view('wishlist', compact('user', 'wishlists'));
}
Also, if I am correct, your product relation is wrong.
Your wishlist should have many products (rather than the other way around).
In your frontend, you will need to loop through all of the wishlist's products:
#foreach($wishlist->products as $product)
{{ $product->price }}
#endforeach
Change the relation in your Wishlist class to hasMany:
public function products()
{
return $this->hasMany(Product::class);
}

Related

wishlist not showing laravel

I'm creating a wishlist ,so that user can be able to save item to wishlist. I have products table, wishlist table which has user_id and product_id columns and also I have pivot table product_wishlist table which has foreign key product_id and wishlist_id. The problem is it doesn't display the product information like price, name etc and it shows no errors, I don't know if my relations are wrong or there is something else, how can I fix this ?
Wishlist.php
class Wishlist extends Model
{
protected $table = "wishlist";
protected $fillable=['product_id','user_id'];
public function user(){
return $this->belongsTo(User::class);
}
public function product(){
return $this->belongsToMany(Product::class,'product_wishlist','wishlist_id', 'product_id');
}
}
Product.php
public function wishlist(){
return $this-belongsToMany(Wishlist::class);
}
Wishlist controller
public function index()
{
$user = Auth::user();
$wishlists = Wishlist::with('product')
->where('user_id', $user->id)
->orderby('id', 'desc')
->paginate(6);
//dd($wishlists);
return view('front.wishlist', compact('user', 'wishlists'));
}
Blade
#foreach($wishlists as $wishlist)
<h3 >USD {{$wishlist->name }}</h3>
<h4 >USD {{$wishlist->price }}</h4>
#endforeach
You will need to do
{{ $wishlist->product->price }}
As the price is an attribute on the product you need to access the product object before accessing the price.

Laravel how to loop through array in controller and combine relationship

In my laravel-application I have a blogs- and an author-table. On the index page, where you see all published blog posts, I want the authors name to appear. So I tried to do this:
public function index()
{
$blogs = Blog::where("publishes_on", "<=", Carbon::now())
->orderBy('publishes_on', 'desc')
->published()
->get();
foreach ($blogs as $blog) {
$author = Author::where('id', $blog->author_id)->get();
}
return view('app.blog.index', compact('blogs', 'author'));
}
For some reason I do not know, this gives me the last added author to my application and on each post, the name of that author is displayed on all posts.
What am I doing wrong here?
In Blog model add author relation
public function author()
{
return $this->belongsTo(Author::class);
}
In controller
$blogs = Blog::where("publishes_on", "<=", Carbon::now())
->orderBy('publishes_on', 'desc')
->published()
->with('author:id,name')
->get();
In view you can use
#foreach($blogs as $blog)
// blog related data
Author: {{ $blog->author->name ?? '' }}
#endforeach
No need for the foreach loop
Blog::with('author')->where( [...]`
In your view
$blog->author->name
Make sure you define author() as a relationship on the Blog model:
https://laravel.com/docs/master/eloquent-relationships
e.g.
class Blog {
function author(){
return $this->belongsTo(Author::class);
}
}

Laravel : load objects on many level

I have the following tables :
orders : id, etc...
order_lines : id, order_id, product_id, etc...
products : id, name, etc...
Foreign keys are defined.
My Laravel Models are defined as :
class Order
public function orderLine()
{
return $this->hasMany('App\OrderLine');
}
class OrderLine
public function order()
{
return $this->belongsTo('App\Order');
}
public function product()
{
return $this->belongsTo('App\Product');
}
class Product
public function orderLine()
{
return $this->hasMany('App\OrderLine');
}
I've tried many things, but nothing is working. Here is the best solution for me, but it's not working.
class OrderController
public function show($id)
{
$user = Auth::user();
$order = Order::where('user_id', '=', $user->id)->with(['orderLine.product'])->findOrFail($id);
return view('layouts/order/index', compact('order'));
}
I struggle to display the following data in the view :
#foreach($order->orderLine as $key => $orderLine)
<tr>
<td>{{$orderLine->product->name}}</td>
<tr>
#endforeach
Product object is not loaded. I want to display the product name in the above loop.
Try to do like this:
public function show($id)
{
$user = Auth::user();
$order = Order::with(['orderLines', 'orderLines.product'])
->where('user_id', '=', $user->id)
->findOrFail($id);
return view('layouts/order/index', compact('order'));
}
class OrderLine
public function order()
{
return $this->belongsTo(\App\Order::class, 'order_id');
}
public function product()
{
return $this->belongsTo(\App\Product::class, 'product_id');
}
class Order
public function orderLines()
{
return $this->hasMany(\App\OrderLine::class);
}
Change name of orderLine to orderLines because order has many orderLines.
And in your blade:
#foreach($order->orderLines as $orderLine)
<tr>
<td>{{$orderLine['product']->title}}</td>
<tr>
#endforeach
Hello Dezaley and welcome to StackOverflow!
Let's investigate your problem.
As far as I can see you are selecting the model in the wrong way. Let me help you:
$order = Order::where(['id' => $id, 'user_id' => $user->id])->with('orderLine.product')->firstOrFail();
The answer from mare96, who was very friendly to help me, is working. However, I found out someting.
You can implement as (mare96 solution)
public function show($id)
{
$user = Auth::user();
$order = Order::with(['orderLines', 'orderLines.product'])
->where('user_id', '=', $user->id)
->findOrFail($id);
return view('layouts/order/index', compact('order'));
}
#foreach($order->orderLines as $orderLine)
<tr>
<td>{{$orderLine['product']->title}}</td>
<tr>
#endforeach
In the view, I don't like the array syntax "$orderLine['product']->title". The following solution without the array is also working.
Solution is below :
public function show($id)
{
$user = Auth::user();
$order = Order::with('orderLines', 'orderLines.product')
->where('user_id', '=', $user->id)
->findOrFail($id);
return view('layouts/order/index', compact('order'));
}
#foreach($order->orderLines as $orderLine)
<tr>
<td>{{$orderLine->product->title}}</td>
<tr>
#endforeach
In fact, my issue was that product was defined to null in the model, so Product was always null in the view.
Class OrderLine extends Model {
public $product = null
I remove line "public $product = null" and it's working as expected. Thanks to the people who helped me.
give it a try -
#foreach($order as $ordr)
<tr>
<td>{{$ordr->product_id->name}}</td>
<tr>
#endforeach

How to create a relationship between User and Posts in Laravel

I have a blog and want to include the Users Name when shown to the public.
When creating the blog I make sure to include the user_id in the blogs table
In my Blog model I have the following:
public function users()
{
return $this->belongsTo(User::class);
}
In my Users model I have:
public function blogs()
{
return $this->hasMany(Blog::class);
}
In my Blog Controller I have:
public function index(User $user)
{
$users = User::get();
$blogs= DB::table('blogs')->where('user_id', '=', $users->id)->orderBy('id', 'DESC')->paginate(6);
return view('blogs.index',compact('blogs'));
}
Then in my view:
#foreach($blogs as $blog)
<h1>{{$blog->title}}</h1>
Source:{{$blog->users->first_name}} // This does not work
Source:{{$blog->first_name}} // This does not work either
#endforeach
I thought I could do something like this to show the names:
{{ $blogs->users->first_name }} {{ $blogs->users->last_name }}
But this isn't working either...
Try this:
#foreach($blogs as $blog)
<h1>{{$blog->title}}</h1>
{{$blog->user->first_name}}
#endforeach
And on your Blog Model
public function user()
{
return $this->belongsTo(User::class);
}
In your Blog controller the variable $blog needs to be $blogs. You also have extra characters (right parenthesis) in your Blade. It should be:
#foreach($blogs as $blog)
Source: {{ $blog->user->first_name }}
...
#endforeach
Blog Model
This function replaces the old "users" function, as only one user is returned (belongsTo is a singular relationship).
class Blog extends Model
{
public function user()
{
return $this->belongsTo('App\User');
}
}
User Model
public function blogs()
{
return $this->hasMany('App\Blog');
}
Controller Function
And, as such, you can cut down your controller code, including removing the redundant elements.
public function index(User $user)
{
$blogs = Blog::where('user_id', '=', $user->id)->orderBy('created_at','desc')->paginate(6);
return view('blogs.index', compact('blogs'));
}
The way you did is called Query Builder
$blogs= DB::table('blogs')->where('user_id', '=', $users->id)->orderBy('id', 'DESC')->paginate(6);
Query Builder does not support lazy loading, cause lazy loading is only supported for the Eloquent method
$blog->users->first_name
For Eloquent way you can try this instead:
$blogs = Blog::where('user_id', $user->id)->get()
foreach($blogs as $blog){
dd($blog->user); // you will get the user detail here
}
For lazy loading have a performance issue when come to load heavy data so to prevent lazy loading can use this
$blogs = Blog::with('user')->where('user_id', $user->id)->get()
For more information can look at Eloquent Relationship Documentation
For query builder, the only way to link your user is use join, which will be something like this
$blogs = DB::table('blogs')
->join('users', 'users.id', '=', 'blogs.user_id')
->get();
foreach($blogs as $blog){
dd($blog->first_name) // user first name
}
For more information can look at Query Builder Join
BlogController.php
public function index(){
$blogs = Blog::with('user')->get();
return view('blogs.index')->with('blogs',$blogs);
}
Blog.php
public function user()
{
return $this->belongsTo('App\User');
}
User.php
public function blogs()
{
return $this->hasMany('App\Blog');
}

Three tables in Laravel 5 with help Eloquent models

maybe this is a simple problem but for me, am I newbie in Laravel, it's problem, so I have three table
Articles, User, Comments. They have this relationship
In page http://localhost/users/{user_name} I want to get all articles and all comments that belongs to this user.
Three Model looks like this:
User
public function articles()
{
return $this->hasMany('App\Article');
}
public function comments()
{
return $this->hasMany('App\Comment');
}
Article
public function user()
{
return $this->belongsTo('App\User');
}
public function comments()
{
return $this->hasMany('App\Comment');
}
and
Comment
public function user()
{
return $this->belongsTo('App\User');
}
public function article()
{
return $this->belongsTo('App\Article');
}
My Controller Show method looks like this:
public function show(User $user)
{
$user->with(['comments','articles'])->get();
return view('users.show', compact('user', 'comments', 'articles'));
}
In view I have everything what I need
{{ dump($user) }}
{{ dump($user->articles) }}
{{ dump($user->comments) }}
{{ dd() }}
and with foreach I get needed attributes, but how do I create link where I can see link to article and comment to her
#foreach($user->comments as $comment)
<div class="block">
//article title
<div></div>
<div>{{ $comment->comment }}</div>
#endforeach
To show article I use title of article, not ID.
Thanks
First, 'comments' and 'articles' here don't do anything.
return view('users.show', compact('user', 'comments', 'articles'));
As for the link,
{{ $comment->article->title }}
I resolved this issue, updated my controller:
public function show(User $user)
{
$params = Comment::where('user_id', $user->id)->get()
return view('users.show', compact('user', 'params'));
}
It's works like I need but I think that there are better way to resolve this.

Categories