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 ?
Related
I've spent two days trying to solve this but I can't figure how.
I have five tables
Product
Category
Category_Product
Order
Order_Product
From the view,clicking on a category button I have to fetch all his ordered products with the relative category.
I have the current models:
Product Model
class Product extends Model
{
public function categories() {
return $this->belongsToMany('App\Category');
}
public function orders() {
return $this->belongsTo('App\Order');
}
}
Category Model
public function products() {
return $this->belongsToMany('App\Product');
}
Order Model
public function products() {
return $this->belongsToMany('App\Product');
}
Now the problem is that I can't figure how to fetch the data from the current tables.When I press a button I'm able to fetch the category from the Product Table,but I want to fetch from the Ordered_Products. I really can't figure how.
With this I'm able to fetch all the categories from Product
if (request()->category) {
$products = Product::with('categories')->whereHas('categories', function ($query) {
$query->where('slug', request()->category);
})->get();
}
With this instead,I'm able to fetch the ordered products.
$products = DB::table('order_product')
->join('products', 'order_product.product_id','=', 'products.id')
->where('order_product.user_id','=',$user_id)
->get();
For the latter, there's a better way to do it, that's for sure. I'm sorry if it's a dumb question but I'm rather new with this framework. I am using Laravel 7.2.
Basically Eloquent Model doesn't encourage joining tables to retrieve data. It should be joined only for filtering results (So you need to drop field of other table using ->select('original_table.*'))
In this case, you should simply retrieve categories at first. Then retrieve related data using relation property accessing.
e.g.
$categories = Category::query()
->with('products')
->where('slug', request('category'))
->get();
$products = $categories->flatMap->products;
$pivots = $products->map->pivot;
Solved using whereHas two times:
$products = Product::with('categories')->whereHas('categories',function($query){
$query->where('slug',request()->category);
})->whereHas('orders',function($query){
$query->where('orders.user_id',Auth::id());
})->get();
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 two tables
product: id|category ...
category: id|name ...
product.category is a foreign key linked to category.id . I am building a basic CRUD and I would like to display all Products in the the product table as well as the name of the category they belong to rather than their category ID. TO do this, while searching the laravel documentation I came across the query builder and I achieved my goal.
public function index()
{
$products = \DB::table('products')
->join('categories', 'products.category', '=', 'categories.id')
->select('*')
->get();
return view('product' ,compact('products'));
}
Under my models for product and category I have created the appropriate relationships.
product.php :
public function category()
{
return $this->belongsTo('App\Category');
}
category.php :
public function products()
{
return $this->hasMany('App\Product');
}
I keep hearing about the power of Eloquent and was wondering how I could achieve a similar result with eloquent and if eloquent is designed for such operations or if the query builder is the right way to go.
Every tutorial online seems to only use the post and comments scenario of getting all comments belonging to a post.
You can use this code
public function index()
{
$products = Product::with('category')->get();
return view('product' ,compact('products'));
}
In blade
#foreach($products as $product)
{{$product->name}}
{{$product->category->name ?? ''}}
//or
#if ($product->category)
$product->category->name
#endif
#endforeach
Also if in project table foreign key is not equal category_id. In your case
public function category()
{
return $this->belongsTo('App\Category', 'category');
}
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.
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();
}