I want show my brands page like: url/discount/{brand-slug} so far i can get it done by something like:
$brandspromotion = Brand::where('slug', $slug)->OfStatus('Active')->firstOrFail();
problem occurs when I try to get only products with same brand_id which their id is saved in 3rd table named discounts.
In the simple words: I want to get only discounted products of each brand.
LOGIC
Discounts table saves product_id
Products table saves brand_id
Brand has to find it's own id from products through discounts table.
Code
so far I have this code, which is not working :)
public function brandspromotions($slug) {
$promotions = Discount::Valid()->get();
$grouped = $promotions->map(function ($item, $key) {
return $item->products->brand_id;
});
$brandspromotion = Brand::where('slug', $slug)->OfStatus('Active')
->where('id', $grouped)->get();
return view('front.brandspromotions', compact('brands', 'brandspromotion'));
}
UPDATE
product model
public function discount(){
return $this->belongsTo(Discount::class, 'product_id', 'id');
}
public function brand(){
return $this->belongsTo(Brand::class);
}
brand model
public function products(){
return $this->hasMany(Product::class);
}
discount model
public function products(){
return $this->belongsTo(Product::class, 'product_id', 'id');
}
If you have a brand slug and you want to get only products of this brand which have a record in the discounts table:
Product::has('discount')
->whereHas('brand', function($q) use($slug) {
$q->where('slug', $slug);
})
->get();
Where discount and brand are the relationships defined in the Product model.
Related
I have few products in 3 category (for example), and each product has a brand. I want to show brands which related to products in a specific category.
Models:
--product
--brand
--category
relations:
category has many products
brand has many products
How can I do that?
Considering you have 3 models with relationships like :
Brand Model :
public function products()
{
return $this->hasMany(Product::class);
}
Product Model :
public function brand()
{
return $this->belongsTo(Brand::class);
}
public function category()
{
return $this->belongsTo(Category::class);
}
Category Model :
public function products()
{
return $this->hasMany(Product::class);
}
You can use whereHas :
$brands = Brand::whereHas('products.category', function ($q){
return $q->where('name', 'category_name');
})->get();
Above will give you all brands which has product belonging to category with name as category_name.
If you want to get product and category details then you can eager load :
$brands = Brand::whereHas('products.category', function ($q){
return $q->where('name', 'category_name');
})->with(['products', 'products.category'])->get();
I have collections which contains custom products I need to paginate those collections products but I receive error.
data
With this query I can get my collection and it's products but I'm not able to paginate products.
$collection = Collection::where('slug', $slug)->where('status',
'active')->with('products')->first();
With this query I receive error
$collection = Product::with('collections')->whereHas('collections',
function($query) use($slug) { $query->where('slug',
$slug)->where('status', 'active')->first(); });
Error
SQLSTATE[42S02]: Base table or view not found: 1146 Table 'shopping.product_id' doesn't exist (SQL: select * from `collection_products` inner join `product_id` on `collection_products`.`id` = `product_id`.`collection_product_id` where `products`.`id` = `product_id`.`product_id` and `slug` = test and `status` = active limit 1)
Code
Product model
public function collections()
{
return $this->belongsToMany(CollectionProduct::class, 'product_id');
}
Collection model
public function collection(){
return $this->belongsToMany(CollectionProduct::class);
}
public function products(){
return $this->belongsToMany(Product::class, 'collection_products', 'collection_id', 'product_id');
}
CollectionProduct model
public function collection()
{
return $this->belongsTo(Collection::class, 'collection_id','id');
}
Controller default query
public function single($slug){
$collection = Collection::where('slug', $slug)->where('status', 'active')->with('products')->first();
return view('front.collections.single', compact('collection'));
}
Question
How can I get my collection products with pagination ability?
Couple things:
You are trying to call the first() method inside of a relationship query in this line:
$collection = Product::with('collections')->whereHas('collections', function($query) use($slug) { $query->where('slug', $slug)->where('status', 'active')->first(); });
The methods first() and get() are used to execute the query, so you should keep them at the end of the chain of eloquent methods:
$collection = Product::with('collections')
->whereHas('collections', function($query) use($slug) {
$query->where('slug', $slug)->where('status', 'active');
})
->get();
https://laravel.com/docs/5.7/eloquent#retrieving-models
However, if you want to paginate the list of products, then what you really want is the paginate() method:
$collection = Product::with('collections')
->whereHas('collections', function($query) use($slug) {
$query->where('slug', $slug)->where('status', 'active');
})
->paginate(20); // will return 20 products per page
https://laravel.com/docs/5.7/pagination
Also, the collections() method on your Product model has product_id listed as the join table, and is joining to the CollectionProduct model instead of the Collection model.
Try this instead for your Product model:
public function collections()
{
return $this->belongsToMany(Collection::class, 'collection_products', 'product_id', 'collection_id');
}
i use following code and working very well
the first step get product
$product = Product()->find($product_id);
than i get collections and pagination
$collections = Product::find($product_id)->collections->paginate(20);
for example i used above code in this site.
I have categories and products tables. They are related with Many to Many relationships.. I want to get products by categories and selected price range but whereHas clause dosen't work
$products = Product::whereHas('categories',function ($query) use ($slug){
$query->where('category_slug',$slug);
})->whereBetween('price',[100,200])->get();
Category Model;
public function products(){
return $this->belongsToMany('App\Product','category_product','category_id','product_id');
}
Product Model;
public function categories() {
return $this->belongsToMany('App\Category','category_product','product_id','category_id');
}
So, what is my mistake in here ?
I have three tables - users, products and orders
There is a relation between users and orders (users has many orders).
orders table contains product_id and user_id column.
Now I want to access the product details of orders for a user.
What I am trying:
public function myOrders(){
$orders = Auth::user()->orders->pluck('product_id');
$products = Product::find($orders);
return view('shop.myorders', compact('products'));
}
But this is not working. Can anyone help me? What other way can be better to achieve this?
As mentioned, find() will always return 1 item, and expects a string/int for the parameter. You want to use where and get instead. With an array of ids, you can use whereIn.
public function myOrders(){
$orders = Auth::user()->orders->pluck('product_id');
$products = Product::whereIn('id', $orders)->get();
return view('shop.myorders', compact('products'));
}
I assume you have orders() relation defined in the Product model:
public function orders()
{
return $this->hasMany(Order::class)
}
Then you'll be able to load products from all user's orders:
$products = Product::whereHas('orders', function($q) {
$q->where('user_id', auth()->id())
})->get();
I have two tables, say Products and Biddings where one product can be bid by many users. Naturally I have two models:
class Product extends Model
{
public function biddings()
{
return $this->hasMany('App\Bidding');
}
}
class Bidding extends Model
{
public function product()
{
return $this->belongsTo('App\Product');
}
}
So, say I want to get all products along with the highest priced bidding I did something like this.
$productBidding = DB::table('biddings')
->select('*', DB::raw('max(price) as price'))
->join('products', 'products.id', '=', 'biddings.product_id')
->groupBy('product_id')
->get();
That works well BUT I kinda want to do it Eloquent way. So how do I convert Query Builder way to Eloquent? I am currently on this but do not know how to put the "max" condition in.
$productBidding = Products::with('biddings')
->get();
$productbinding=Bidding:with('product')
->get();
foreach($productbinding as $productbind)
{
echo $productbind->product->name; // example
}
I would extract the highest bid to a separate function on the Product model, like so:
public function highestBid() {
return $this->biddings()->max('price');
}
Then fetch the products and get the highest bid:
$products = Product::get();
foreach ($products AS $product) {
echo $product->highestBid();
}