How to select specific column from parent and child in laravel - laravel

Please see my code below.
Controller
$orders = Order::with('product:id,name')
->select([
'id',
'order_number',
'ordered_on',
'status',
'total'
])
->where('customer_id', session('customer_id'))
->orderBy('ordered_on', 'DESC')
->paginate(6);
dd($orders);
Order model
public function product()
{
return $this->belongsTo(Product::class);
}
The result above returns null when you check the product relationship data.
What I need
Select specific columns from Order model, then select specific columns from product relationship.

You need to add the foreign key that you are referencing:
->select([
'product_id'
...
])
...
When using this feature, you should always include the id column and any relevant foreign key columns in the list of columns you wish to retrieve.
Docs: https://laravel.com/docs/9.x/eloquent-relationships#eager-loading-specific-columns

Related

How to query count on the pivot table in Laravel eloquent

I have two data tables in database. One is user table, other one is property table. User can save as many properties as they want. Also, one property can be save by multiple users. So there is a pivot table which has the property_id and user_id in it for a record. Now I want to query the popular properties. All properties that is saved by more than 100 users are popular properties. How would I do that? Something like I am doing
public function popularProperties(Request $request)
{
$id = $request->id;
return Property::where('saved'->count(),'>',100)->with([
'paymentPlan' => function ($query){
$query->select('property_id','all_in_one_go','down_payment','minimum_installment_per_month');
},
'city',
'propertyType' => function ($query){
$query->select('id','name');
},
'user' => function ($query){
$query->select('id','name','email');
},
'images' => function($query){
$query->select('imageable_id','url');
}
])->withCount('likes')->get();
}
The following code selects all property's with > 100 count. Inside the whereIn is a subquery that selects all property IDs that exist > 100 times. Note that you have to fill in the correct Table and column names
$propertys = Property::whereIn('id', function ($q){
$q->select('property_id')
->from('user_property')
->groupBy('property_id')
->havingRaw('COUNT(*) > 100');
})->get();

Laravel Eloquent with() selecting specific column doesn't return results

Say I have 2 models, Category and POI where 1 Category can have many POIs.
$categoryDetails = Category::with([
'pois' => function ($query) {
$query->where('is_poi_enabled', true);
},
])->findOrFail($id);
The above query returns results from the specific Category as well as its POIs.
However, with the query below:
$query->select('id', 'name')->where('is_poi_enabled', true);
The POIs become empty in the collection.
Any idea why this is happening? When added a select clause to the Eloquent ORM?
While doing a select it's required to fetch the Relationship local or Primary key.
For an example POIs table contains category_id then it's required to select it
Try this:
$categoryDetails = Category::with([
'pois' => function ($query) {
$query->select(['id', 'category_id', 'is_poi_enabled'])
->where('is_poi_enabled', true);
},
])->findOrFail($id);
Good luck!

Laravel eloquent table joined to itself, how to get 1 array with all values

I am using a table employee that is joined to itself for the manager.
Employee
id
name
manager_id (FK to Employee)
I am using the following model for Employee:
public function my_employees()
{
return $this->hasMany('App\Employee', 'manager_id');
}
public function my_manager()
{
return $this->belongsTo('App\Employee', 'manager_id');
It is working fine because I can use the my_employees function on an employee and it will get me all the records linked to this employee.
Now I would like to get a table with all the employees where the column manager_id is replaced by manager_name. How can I achieve this with Eloquent?
Not using Eloquent, I do:
$employee = DB::table('employee')
->select('employee.id', 'employee.name', 'employee.manager_id','manager.name AS manager_name')
->join('employee AS manager', 'employee.manager_id','=','manager.id');
This gets me of course what I want but I would like to understand how to do it with Eloquent only.
Thanks.
Exactly the same way.
$employees = Employee::select('employee.id', 'employee.name', 'employee.manager_id', 'manager.name AS manager_name')
->join('employee AS manager', 'employee.manager_id', '=', 'manager.id')
->get();
You could also do this shown below. But then you need to access the manager name from the relationship object.
$employees = Employee::with('my_manager')->get();
foreach($employees as $employee) {
echo $employee->my_manager->name;
}
Edit
You can add any constraint to the eager loaded relationship.
$employees = Employee::with(['my_manager' => function($query) {
$query->select('manager_id', 'name');
}])->get();

Advanced Select statement (Laravel)

In the Products table i have the store_id column which connects the product with the store.
In my APIController which i use with Angular i have this return statement. I am returning a collection of products.
return Product::where('category_id', $category->id)
->select(array('id', 'name', 'newprice', 'image',
'store_id', 'link'))
->paginate(20);
My problem is that instead of returning the store_id(from the products table) i want to return the store name, which is NOT stored in the same table. Is there any way to do that?
Is my only option the use of JOIN?
I recommend you do it with Laravel(/Eloquent) relationships like this:
ApiController:
$productFieldArray = ['id', 'name', 'newprice', 'image', 'store_id', 'link'];
$product = Product::where('category_id', $category->id)
->select(productFieldArray)
->paginate(20);
// Get the value you want (I guess it's the name attribute?)
$store = $product->store->name;
Model relationships:
Product.php:
...
public function store() {
return $this->belongsTo('App\Store');
}
...
Store.php:
...
public function products() {
return $this->hasMany('App\Product');
}
...
Edit:
You have to use the with() function in your query to point out your want to receive the store data too. See: Laravel - accessing relationship Models with AngularJS or http://laravel.com/docs/4.2/eloquent#eager-loading.
So you query will be:
Product::with('store')
->where('category_id', $category->id)
->select(productFieldArray)
->paginate(20);

How to select field in another table join by eager loading in Laravel

I got category_to_news and news_main table
category_to_news
news_id int
name varchar
title timestamp
news_main
id int
title varchar
image varchar
created_at timestamp
how to return by news_main's field and category_news's field ? I've tried this method and it's not work
$posts = Categorytonews::with(array(
'Newsmain' => function($query)
{
$query->orderBy('id', 'DESC')->select(array('title', 'id', 'created_at', 'image'));
}
))
->get( );
You need join for this because with() runs another query, so ordering there won't do the job:
$posts = Categorytonews::with('Newsmain') // get all fields from Newsmain
->join('news_main', 'category_to_news.news_id', '=', 'news_main.id') // join for ordering
->orderBy('news_main.id','desc') // order by joined field
->get('category_to_news.*'); // select only main table, you don't need joined fields
// on Categorytonews model - they will be loaded by with()
$posts = Categorytonews::with(array('Newsmain' => function($query)
{
$query->select(array('title', 'id', 'created_at', 'image'))->orderBy('id', 'DESC');
}))->get();

Resources