Get only one column from relation - laravel

I have found this: Get Specific Columns Using “With()” Function in Laravel Eloquent
but nothing from there did not help.
I have users table, columns: id , name , supplier_id. Table suppliers with columns: id, name.
When I call relation from Model or use eager constraints, relation is empty. When I comment(remove) constraint select(['id']) - results are present, but with all users fields.
$query = Supplier::with(['test_staff_id_only' => function ($query) {
//$query->where('id',8); // works only for testing https://laravel.com/docs/6.x/eloquent-relationships#constraining-eager-loads
// option 1
$query->select(['id']); // not working , no results in // "test_staff_id_only": []
// option 2
//$query->raw('select id from users'); // results with all fields from users table
}])->first();
return $query;
In Supplier model:
public function test_staff_id_only(){
return $this->hasMany(User::class,'supplier_id','id')
//option 3 - if enabled, no results in this relation
->select(['id']);// also tried: ->selectRaw('users.id as uid from users') and ->select('users.id')
}
How can I select only id from users?

in you relation remove select(['id'])
public function test_staff_id_only(){
return $this->hasMany(User::class,'supplier_id','id');
}
now in your code:
$query = Supplier::with(['test_staff_id_only:id,supplier_id'])->first();

There's a pretty simple answer actually. Define your relationship as:
public function users(){
return $this->hasMany(User::class, 'supplier_id', 'id');
}
Now, if you call Supplier::with('users')->get(), you'll get a list of all suppliers with their users, which is close, but a bit bloated. To limit the columns returned in the relationship, use the : modifier:
$suppliersWithUserIds = Supplier::with('users:id')->get();
Now, you will have a list of Supplier models, and each $supplier->users value will only contain the ID.

Related

Eloquent hasMany with foreign key on joint table

Assume this:
class List extends Model
{
public function items(){
return $this->hasMany(Items::class, 'c.class_id', 'class_id')
->rightjoin('items_classes as c', 'c.items_id', '=', 'items.id');
}
}
The problem is that Eloquent prepends items to foreign key field and the final query is:
SELECT * FROM items
RIGHT JOIN items_classes as c ON c.items_id = items.id
// here it is
WHERE items.c.class_id = 10
Even using DB::raw('c.class_id') didn't solve the problem.
If you notice the signature of hasMany relation method :
return $this->hasMany(Model::class, 'foreign_key', 'local_key');
Which means when Laravel will make the query, it will consider second argument foreign_key as a column of table defined in Model::class.
To simplify in your case :
return $this->hasMany(Items::class, 'c.class_id', 'class_id')->...
Leaving the rightjoin aside for a moment, Laravel is considering c.class_id as a foreign key of Item::class table which is indeed items table.
So the resultant query is :
SELECT * FROM items WHERE items.c.class_id = 10
Then when you add the right join, laravel just adds into the main query and makes it :
SELECT * FROM items
RIGHT JOIN items_classes as c ON c.items_id = items.id
WHERE items.c.class_id = 10
Laravel will not refer items_classes in the relation because you are relating List Model to Item::class and not ItemClass::class.
I am not sure about the data you need but see if you can use with like below :
class List extends Model
{
public function items(){
return $this->hasMany(Items::class, 'c.class_id', 'class_id');
}
}
List::with(['items', function($q){
return $q->->rightjoin('items_classes as c', 'c.items_id', '=', 'items.id');
}])->get();
Hope this gives you an idea how you can update your relationships to get desired query. If you add your table structure and data you want, I can update the answer with relationships for you.

Laravel Fetching one to Many Relationship

Hello I am learning laravel and I am having an issue retrieving data from my relations.
In my database there are Product and Groups filled with dummy data.
I defined my relationship like this in product model:
public function Group()
{
return $this->hasMany('App\Groups','product_id', 'id');
}
And in my group vice versa with :
public function Product()
{
return $this->belongsTo('App\Product','product_id', 'id');
}
The way I am referencing to my products table is :
$table->foreign('product_id')->references('id')->on('products')->onDelete('cascade');
Now I have column product_id in my database under groups, and it is linked to if from products id it seems.
The groups table contains of its auto incremented id and product_id foreign key column.
While products table has auto incremented id and name column.
The issue is here :
How do I return the products that are not null or have value (of products id) in groups table.
I tried something like this in my filter controller:
public function getProductsWithGroup()
{
$Products = Product::with('groups')->get();
return $Products ;
}
But that is giving me call to undefined relations.
I am not sure how to access belongsTo or hasMany methods and whether I need an extra group_id column in my products table.
You named the relationship wrong. It should be groups & define in lowercase as
public function groups()
{
return $this->hasMany('App\Groups','product_id', 'id');
}
And use ->has() to check existence
public function getProductsWithGroup()
{
$Products = Product::has('groups')->get();
return $Products ;
}
->with() is used to eager load and ->has() is used to check existence & filter.
To get the products don't have any groups,
$Products = Product::doesntHave('groups')->get();
To see other ways to use ->has() check, https://laravel.com/docs/5.7/eloquent-relationships#querying-relationship-existence

Laravel Left join multiple tables and return the original table value

I'm having issues with joining three tables and getting the original table value back.
I have a parent table which is a store that needs to find the brand_id for the products within the store. I can't access the brand_id directly so I need to join, I have to join on to the stores product list then join that onto the product table which holds the brand_id.
$this_return = Store::with('address','setting')
->leftjoin('StoreProducts', function ($join){
$join->on('StoreProducts.store_id', '=', 'stores.id');
})->leftjoin('products', function ($join) {
$join->on('products.id','=','StoreProducts.product_id');
})
->where('products.brand_id', '=', $brandID)
->isActive()
->get();
This is returning a product value, But I wanted it to return all the stores the original table back if the products.brand_id was equal to the $brandID then return the current store and repeat for all stores.
Hope that makes sense
Any help would be great.
I think your relations goes like this:
Stores -> (n*n)StoreProducts -> Products -> (n*1)Brands
which StoreProducts is a joining table between Stores and Products. With this assumption, I would use something like this:
In the Store model,
public function products(){
return $this->belongsToMany(\App\Product::class, "store_products");
}
In the Products model,
public function stores(){
return $this->belongsToMany(\App\Store::class, "store_products");
}
In the StoreProducts model,
public function store(){
return $this->belongsTo(\App\Store::class);
}
public function product(){
return $this->belongsTo(\App\Product::class);
}
This way the relationship is created. Then you can use something like this:
$stores = \App\Store::whereHas("products", function($q) use ($brandId){
return $q->where("brand_id", $brandId);
});
This will give you the stores which the brand exists.

Laravel, How to retrieve parent records with certain Pivot table values belongsToMany

How can I retrieve all records of my model based on certain ID's in my pivot table?
I have the following 3 tables
users;
id,
name
stats;
id,
name
stats_selected;
user_id,
stats_id
Model
User.php
public function stats()
{
return $this->belongsToMany('App\stats', 'stats_selected', 'user_id', 'stats_id')->withTimestamps();
}
Controller
// Get all users with example of stats ID's
$aFilterWithStatsIDs = [1,10,13];
$oUser = User::with(['stats' => function ($query) use($aFilterWithStatsIDs ) {
$query->whereIn('stats_id', $aFilterWithStatsIDs);
}])
->orderBy('name', 'desc')
->get()
This outputs just all the users. Btw, fetching users with there stats and saving those selected stats into the DB is not a problem. That works fine with the above lines.
But how do I retrieve only the users which has certain stats_id's within them?
But how do I retrieve only the users which has certain stats_id's within them?
Use a whereHas conditional.
User::whereHas('stats', function ($stats) use ($aFilterWithStatsIDs) {
$stats->whereIn('id', $aFilterWithStatsIDs);
});

laravel - eloquent - get sum of related model specific column

assuming that I have the table
orders
with fields
id, userId, amount, description
and the table
user
with various fields
how if I wand to get all the users (with all its fields) and also the sum of the "amount" column of the orders related to that user?
assuming that I have:
user:{id:15,firstName:jim,lastName:morrison,gender:male}
and
order:{id:1,userId:15,amount:10,description:"order xxx"},
order:{id:3,userId:15,amount:40,description:"order yyy"}
I would like to receive:
user:{id:15,firstName:jim,lastName:morrison,gender:male,orderAmount:50}
Of course I would like to avoid the foreach statement.
I've setted this on my user model
public function userOrder (){
return $this->hasMany('Order', 'userId');
}
And I've tryed this:
return $this->hasMany('Order', 'userId')->sum('amount');
without any luck...
Some thaughts and hopefully an answer to your question:
I would rename the user table to users to stick to laravel conventions.
http://laravel.com/docs/4.2/eloquent#basic-usage
I would name the method in the User model orders
public function orders()
{
return $this->hasMany('Order', 'userId');
}
To query a user, his orders and sum afterwards his orders amount values:
$userdata = User::with( 'orders' )->where( 'userId', 15 )->first();
$sum = $userdata[ 'orders' ]->sum( 'amount' );

Resources