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();
Related
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'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();
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 a the model Cart with the attributes id, clientIp, completed. I have another model that called Item. Item Model has a belongsTo relationship to Cart Model. and the Cart Model has hasMany relationship to Item model. so far so good.
How can I fetch all the $items that their $cart->completed is true?
I'm really sorry if I haven't explained well my question, I tried my best.
You can try this..
$items = Item::whereHas('cart', function($q) {
$q->where('completed', '=', 'true')
})->get();
Item::whereHas('cart', function($query) {
$query->where('completed', true);
})->get();
You are simply saying:
Give me the items which have a cart that it's completed attribute is true.
In the official documentation there is an example with posts and comments.
$posts = Post::whereHas('comments', function ($query) {
$query->where('content', 'like', 'foo%');
})->get();
This query will get all the posts that have a comment like foo*.
I have a many-to-many relation between Order and Item table.
This relationship is defined in Order model:
public function items()
{
return $this->belongsToMany('Item', 'order_item', 'order_id', 'item_id' );
}
If customer is adding an item to the order, he choose one item from a list
$items = Item::all();
and this chosen item is add in intermediate (pivot) table (order_id, item_id).
The problem is that, I need my items list to contains only these items which have NOT been chosen for this order before. i.e. pivot table does NOT contains these items combined to this specific order.
Pseudo code:
$all_Items = Item::all();
$previously_Selected_Items = select_From_Pivot_Table::where('order_id', '=', $id);
$required_Items_List = $all_items->exclude($previously_Selected_Items);
I'm using Laravel 4.2.
Any suggestions??
Thanks in advance.
You can use whereDoesntHave and filter the items using the relationship:
$items = Item::whereDoesntHave('orders', function($q) use ($id){
$q->where('order_id', $id);
})->get();
After some time of searching and trying some suggested ideas, I came up with easy, but not professional, solution:
$order = Order::where('id', '=', $id)->with('items')->first();
$allitems= Item::all();
then array_diff, a php function, did the trick:
$items = array_diff($allitems->lists('name','id'), $order->items->lists('name','id'));
but the $items is just a list of id and name, not the whole objects, which I need. So I need a better solution.