I'm trying to make a query to the database to retrieve a list of favorite products by category
In the category there is an attribute called sortcode
after that I have a $categoryids : [3242,1231,6343,1232]
and products
$products = Product::find()->where(['category'=>$categoryids])->all();
But the result was not as I expected, item in $products sort by index
Now I want all product in category 3242 should be ranked first, then to 1231 ...
How do I get the results I want?
Sorry for my bad English!
Thanks in advance and have a nice day !!
try to use where in condition
$products = Product::find()
->where(['in','category',$categoryids])
->orderBy('category DESC')
->all();
or if you want to sort it by category's shortcode you should join with categorys table, not tested yet but should works :
$products = Product::find()
->where(['in','category',$categoryids])
->joinWith(['categorys' => function ($query) {
$query->orderBy('shortcode');
}])
->all();
don't dorget to add categorys relations in your Product's model.
public function getCategorys()
{
return $this->hasOne(Category::className(), ['id' => 'category']);
}
Refer Yii2 orderBy()
$products = Product::find()
->where(['category'=>$categoryids])
->orderBy(['here_your_category_id' => SORT_ASC])
->all();
Related
I have a category table, product table.I want to show category wise all products except one specific product id which comes from request
Here is the model relationship
Product Model
public function category(){
return $this>belongsTo(Category::class);
}
CategoryModel
public function products(){
return $this->hasMany(Product::class);
}
I'm getting all products by this way
$product = Product::findOrFail(10);
$category_products = $product ->category->products;
But I want to get all products except product_id 10. How can I get that?
To show category wise products and exclude specific products from related collection you can query category of product and eager load related products using with but remove your desired product from collection using a closure method
$product = 10;
$category = Category::with(['products'=> function($query) use($product) {
$query->where('id','!=', $prodcut);
}])
->whereHas('products', function (Builder $query) use($product) {
$query->where('id', $product);
})->get();
You can constrain eager relations with the with() method, passing a closure.
$id = 10;
$product = Product::findOrFail($id)
->with(['category.products' => fn ($query) => $query->where('id', '!=', $id)])
->get();
$otherProducts = $product->category->products;
pre php 7.4
$product = Product::findOrFail($id)
->with(['category.products' => function ($query) use ($id) {
return $query->where('id', '!=', $id);
}])
->get();
on second thoughts, a more efficient way might be to just query the products table directly:
$otherProducts = Product::query()
->where('category_id', $categoryId)
->where('id', '!=', $productId)
->get();
Trying to get the count of products by its features(many-to-many)
For instance,
Product::with([’features’])->where(category_id, $category_id)->get();
Product A->feature1->id
/feature2->id
/feature3->id
Product B->feature3->id
/feature4->id
/feature6->id
.....
how could i get product count from each feature (after filtered by product category)
I am not good at explain in wording, tried my best.
Final result
feature 1 -> 19 products
feature 2 -> 5 products
...
Try this:
Select product_id from products where category_id = "'.$category_id.'" group by feature_id;
You should Define relation within your Product and Feature Model
class Product extends Model {
public function features(){
return $this->belongsTo(Feature::class);
}
}
class Feature extends Model {
public function products(){
return $this->hasMany(Product::class);
}
}
I presume each Product has an attribute feature_id which hold the id of the Feature to which it's belongsTo.
$products = Product::with([’features’])->where(category_id, $category_id)->get(); // This query will return list of product
foreach($products as $product){
// You can access $feature of product like this
$feature = $product->feature;
}
Because I have already define the reverse relation between the both Model I can access Product from Feature as well.
$feature->products(); // This will return a collection of Product and I can perform any sort of query on that too
// Like count number of Products
$feature->products()->count();
$feature->products()->first(); // get the first product
$feature->products()->last(); // get the last product
And so on and so fourth
Assuming you have products relationship on the Feature model you can try this!
$features = Feature::withCount(['products' => function($query){
$query->where('category_id', $category_id);
}])->get();
You will have a products_count with each record of the collection.
This will do the trick
with(['products' => function($q) use($category_id){
$q->where('category_id',18);
}])
->find($feature_ids)
->groupBy('feature_type_id');
I've following data structure,
Product
id
name
description
Product Review
id
user_id
product_id
review
rating
status (true/false)
Relationship is one to many i.e. one product has many reviews.
What I want is to load all the products with verified reviews(i.e. reviews with status true)
I've tried following,
$products = Product::with('reviews')->get();
but when I iterate over $products to access reviews like $product->reviews, all the reviews(even status false reviews) are displayed.
Any kind of suggestion is appreciated.
You can add a closure to the with function to add extra filtering.
Product::with([
'reviews' => function ($query) { $query->where('status', true); }
])->get();
Another option is to add a filtered relation function to your product model.
public function verifyedReviews() {
return $this->reviews()->where('status', true);
}
And now call this function in your with clause.
Product::with('verifyedReviews')->get();
try this one by using clousre
$products = Product::with(['reviews' => fuction($query) {
return $query->where('status',true);
}])->get();
you can use WhereHas()
Your code would be:
$products = Product::whereHas('reviews',function($query){
return $query->where('status',true);
})->get();
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'm using Laravel 5 Eloquent and feel confused how to solve this case;
I need to show/get a few articles from each categories. When I used this
$cat = App\Category::with(
array('articles' => function($query) {
$query->orderBy('id', 'DESC');
}))->get();
I got all of articles from categories. But, how to get when I only need five articles from each categories?
You can use take() for that:
$cat = App\Category::with(
array('articles' => function($query) {
$query->orderBy('id', 'DESC');
$query->take(5);
}))->get();