Laravel query order with order_details using id - php

Stuck on this.
I use this same query without Id to get all the successfully get all this data.
$orders = $this->order
->with('orderDetails', 'orderDetails.product')
->today()
->get();
Relationships
Order:
public function orderDetails(){
return $this->hasMany('App\OrderDetail', 'order_id');
}
OrderDetail:
public function order()
{
return $this->belongsTo('App\Order', 'order_id', 'id');
}
public function product()
{
return $this->belongsTo('App\Product', 'id_products', 'id');
}
But trying to use the same thing to get data for a particular order doesn't return the order_details.
public function invoice(Request $request, $id)
{
$ordered = $this->order
->find($id)
->with('orderDetails', 'orderDetails.product');
return response()->json($ordered);
}
Why is it behaving differently when passed an id?

When you use find the query is executed before other directives. You need to be using where:
$ordered = $this->order
->where('order_id', $id)
->with('orderDetails', 'orderDetails.product')
->get();

Try to use just this way:
$ordered = $this->order->find($id);
return response()->json($ordered);
The laravel already turned to relationships based on no mapping that you enter in the model.
In this case, your orderDetails in your response will look like this:
Order: {
Id: "1",
Xpto: "whatever",
OrderDetails: {
Id: "1"
}
}

Related

Laravel - how to use model's ID inside belongs to many relationship query?

Models:
Products
Variants
VariantValue
// Product.php
public function variants()
{
return $this->belongsToMany(Variant::class, 'product_variant', 'product_id', 'variant_id')
->with([
'values' => function ($builder) {
return $builder->whereHas('products', function ($q) {
return $q->where('products.id', $this->id);
});
},
]);
}
// Variant.php
public function values()
{
return $this->hasMany(VariantValue::class);
}
// VariantValue.php
public function products()
{
return $this->belongsToMany(Product::class, 'product_variant_value', 'variant_value_id', 'product_id');
}
The above works if we do the following:
Product::first()->variants()->get()->toArray()
But, it doe NOT work if we do the following (the values array is empty):
Product::with('variants')->get()->toArray()
Meaning the issue is that the product ID is not available inside the belongs to many query:
return $q->where('products.id', $this->id);
Any idea how I can make this work? The goal is to load relationship using:
Product::with('variants')->get()

Laravel Eloquent. I try to intersect two intermediate table. Is there any query more efficient than this?

Laravel Eloquent. I try to intersect two intermediate table. Is there any query more efficient than this ?
Unit Model :
public function products()
{
return $this->belongsToMany('App\Product');
}
public function users()
{
return $this->belongsToMany('App\User');
}
Product Model :
public function units()
{
return $this->belongsToMany('App\Unit');
}
public function users()
{
return $this->belongsToMany('App\User');
}
User Model :
public function units()
{
return $this->belongsToMany('App\Unit');
}
public function products()
{
return $this->belongsToMany('App\Product');
}
Query Eloquent :
Product::get()
->filter(function ($product) {
return $product->units
->pluck('id')
->intersect(auth()->user()->units->pluck('id'))
->isNotEmpty();
})
I try to retrieve all product where product unit is equal user login unit
UPDATE
I think code below is more clean
Product::whereHas('units', function (Builder $query) {
$query->where([
'units.id' => auth()->user()->units->pluck('id'),
]);
})->get();
I think your solutions looks optimal! It looks like a way to compare attributes from two pivot tables in the way
Product::with('users')
->with('units')
->compareAttributesFromPivotTables('attribute_a','attribute_b')
->get();
isn't yet implemented.

Having difficulties displaying all content on my wishlist table

I am trying to retrieve the data on my wishlist table, for a particular user, so far it only retrieves the first data on the table, just returning one array instead of the three in the table with same user id
public function getWishlistByUserId($id){
$wishlists = Wishlist::where('userId', $id)->get();
foreach($wishlists as $wishlist){
$products = Product::where('id', $wishlist->productId)->get();
return $products;
}
}
It happens because the foreach loop returns a value during the first iteration. Place your return statement outside the loop. Also you could improve your performence by making use of relationships.
An example could be:
// Product.php
public function wishlists()
{
return $this->hasMany(Wishlist::class);
}
// Your method
public function getWishlistByUserId($id)
{
return Product::whereHas('wishlists', function ($query) use ($id) {
$query->where('userId', $id);
});
}
Ideally this is n+1 situation
So i will suggest to use laravel relationship like:
in your whishlist model
public function product(){
return $this->hasMany(Product::class,'productId','id');
}
get data with relationship
public function getWishlistByUserId($id){
$wishlists = Wishlist::with('product')->where('userId', $id)->get();
}
I was finally able to get it working this way, i just pushed the result into an array, and then returned it outside the loop, thanks everyone for your help
public function getWishlistByUserId($id){
$wishlists = Wishlist::where('userId', $id)->get();
$wishlist = [];
foreach($wishlists as $wish){
$product = Product::where('id', $wish->productId)->get();
array_push($wishlist, $product);
}
return $wishlist;
}

Laravel relationships belongsToMany

I want to fetch all orders and connect them with their statuses, but I want only the last status for each. I was trying to do it like this, but I only get the status for the first order the rest doesn't have any. How can I fix it?
static function actualKioskOrders()
{
$orders = Order::query();
return $orders->with([
'statuses' => function ($query) {
$query->orderBy('created_at', 'desc')->first();
}
]);
}
In order model add this method, I suggest doing query on model class.
public function status(){
return $this-> belongsToMany(Status::class);
}
public function latestStatus()
return $this->status()->latest()->first();
}
.
I believe the easier way to do it would be
$orders = Order::with('status')->orderBy('created_at', 'desc');
Then if you dd($orders); you will have all the orders with their corresponded status.

Laravel 4.1 eager loading

I'm having trouble on the eager loading.
Let's say I have models of Members, TrainingCategory, TrainingCategoryResult and Registration
Member Model:
public function registration() {
return $this->hasMany('Registration', 'member_id');
}
public function trainingResults(){
return $this->hasMany('trainingResult', 'member_id');
}
public function trainingCategoryResults() {
return $this->hasMany('TrainingCategoryResult', 'member_id');
}
TrainingCategory Model:
public function trainings() {
return $this->hasMany('Training', 'id');
}
public function trainingCategoryResults() {
return $this->hasMany('trainingCategoryResult', 'category_id');
}
TraningCategoryResult Model:
public function category() {
return $this->belongsTo('TrainingCategory', 'id');
}
public function member() {
return $this->belongsTo('Member', 'id');
}
Registration Model:
public function course() {
return $this->belongsTo('Course', 'course_id');
}
public function member() {
return $this->belongsTo('Member', 'id');
}
I am trying to eager load all the registration info and its related info including the TraningCategoryResult info but I not sure how to get that TraningCategoryResult which required two foreign keys (category_id and member_id), is there any way to do that?
Here is my code atm:
$members= Member::where(function($query) use ($id, $site) {
$query
->where('id', '=', $id)
->where('site', '=', $site);
});
$members= $members
->with('registration.course',
'registration.course.traningCategories',
->get(['member.id']);
Thank you.
This will not work Member::with('categoryResult')->with('registration')->get()
You can make a new relation in Member Model
public function categoryResult()
{
return $this->belongsTo('Category')->with('Registration');
}
//and then call
Member::with('categoryResult')->get();
You could use a few options to achieve that:
OPTION 1: create a variable relationship
Change your relation in the Member model
public function trainingCategoryResults($category_id = null) {
if(empty($category_id))
return $this->hasMany('TrainingCategoryResult', 'member_id');
else
return $this->hasMany('TrainingCategoryResult', 'member_id')
->where('category_id', $category_id);
}
The code above might have limitations and it doesn't take advantage of many laravel features, but it will work.
OPTION 2: Access from relationship
You can keep everything as is, and load as follow:
$members= Member::where(function($query) use ($id, $site) {
$query
->where('id', '=', $id)
->where('site', '=', $site);
})
->where('id', $member_id) // set the id of the memeber
->with(array(
'traningCategoryResults' => function($q)use($category_id){
$q->where('category_id', $category_id); // This makes sure you get only desired results
}
))
In this way you will have only what you need, assuming you know the $category_id

Categories