Laravel pluck fields from relations - php

I have a Seller object which has a related User. I need to fill a select from LaravelCollective so I need to make something like this:
{!! Form::selectGroup('seller_id', 'Seller', Seller::with('user')->pluck('user.first_name', 'id')->toArray(), null) !!}
The problem is that I cannot take fields from relationships (user.first_name).
How can I do it?
UPDATE
I want to avoid doing this...
<?php
$sellers = [];
Seller::with('user')->get()->each(function ($seller) use (&$sellers) {
$sellers[$seller->id] = $seller->user->first_name;
});
?>

You can use Laravel's pluck method as:
$sellers = Seller::with('user')->get()->pluck('user.first_name', 'id')

try with below solution it's working for me as i am using laravel 8
$sellers = Seller::with('user')->get()->pluck('user.*.first_name')

You can achieve it by using join() & pluck() like this:
$s = Seller::join('users', 'sellers.user_id', '=', 'users.id')
->pluck('sellers.id', 'users.id')
->all();
This would give an array like this:
[
'seller_id_1' => 'user_id_1',
'seller_id_2' => 'user_id_2',
'seller_id_3' => 'user_id_3',
'seller_id_4' => 'user_id_4',
'seller_id_n' => 'user_id_n',
];
Hope this helps!

Another way to do it is to define what columns you need inside the relationship. It's good if you always need just these columns on the given relationship. Example:
Class Seller extends Model {
...
public function user()
{
return $this->hasOne(user::class, 'id')
->select('id', 'first_name');
}
}

Related

How to get array of nested relations into single Array in Laravel

Item Model:
public function item_makes(){
return $this->hasMany(ItemMake::class,'item_id','id');
}
In ItemMake Model :
public function make(){
return $this->belongsTo(Make::class,'make_id','id');
}
I need to get array of all make based on item_id. How to achieve this? Thanks in Advance.
This worked for me.
$item = Item::findOrFail(1)
->item_makes()
->with('make')
->get()
->pluck('make')
->flatten()
->toArray();
Try something like this:
Item::findOrFail(1)
->with('item_makes.make')
->get()
->pluck('make')
->flatten()
->toArray()
Try wherehas method something like this
$makes = Make::whereHas('item_makes', function ($query) use($item_id) {
$query->where('item_id', $item_id);
})->get();

laravel relation with only get second relation

I am getting the relation of an relation like this:
Application::select()->where('id', $id)->with('vacancie.company:id,title')->get()
now I am getting the full vacancie model. How can I only get the company id and title, excluding the full vacancie model?
If i remember correctly, should be something like this:
Application::where('id', $id)->with([
'vacancie' => function($query) {
$query->select(['id','company_id'])->with([
'company' => function($query) {
$query->select(['id','title']);
}
]);
}
])->get()
try this query :
$details = Application::where('id', $id)->pluck('id','title');

Get other table column value in laravel 5.4

Hello i have below query
Deal::with(array('deal_category'=>function($query){
$query->select('name as dealcategory');
}))->get()
when i try to retrieve dealcategory it does not return any value. I have defined relationship in model like
Deal Model
public function deal_category()
{
return $this->belongsTo('App\DealCategory', 'deal_category_id', 'id');
}
And Deal category model like
public function deals(){
return $this->hasMany('App\Deal','deal_category_id');
}
can anyone help how can i get categoryname?
You have to select the primary key to retrieve the necessary results.
Deal::with(array('deal_category'=>function($query){
$query->select('id', 'name as dealcategory');
}))->get()
Use facade DB.
You can try something like this:
DB::table('deal as d')
->join('deal_category as dc', 'd.id', '=', 'dc.deal_id')
->select('d.name as dealname', 'dc.categoryname')
->get();

Sorting users through relation in laravel

i want to sort the users through voornaam(firstname). but im getting the data via a relation.
How do i make my query so that, the relation users are sorted by firstname by alphabet
my function:
public function sortfirstname($id) {
$ingeschrevenspelers = UserToernooi::with('users')->where('toernooiid', '=', $id)->get()->all();
//This query ^^
$toernooi = Toernooi::findOrFail($id);
dd($ingeschrevenspelers);
return view('adminfeatures.generatespelerslijst', compact('ingeschrevenspelers', 'toernooi'));
}
What i want to sort
any help is appreciated
thanks in advance
Writing code in your own language doesn't make it very easy for other developers to understand your code.
That being said, you can try the orderBy() method on your relationship
In your model where you define the relationship:
public function relationship()
{
return $this->belongsTo(SomeClass::class)->orderBy('name', 'DESC');
}
Don't fire all() function at the end thus obtaining a Collection instance of result
//query without the all function
$ingeschrevenspelers = UserToernooi::with('users')->where('toernooiid', '=', $id)->get();
//
$ingeschrevenspelers = $ingeschrevenspelers->sortBy('users.firstname');
An alternative to Jordy Groote's answer if you do not want to modify the Model class itself, you can query it with a closure.
$ingeschrevenspelers = UserToernooi::with(['users' => function($q) {
$q->orderBy('voornaam', 'asc');
}])->where('toernooiid', '=', $id)->get()->all();
Reference: https://laravel.com/docs/5.3/eloquent-relationships#constraining-eager-loads
Sidenote: I don't think you need a ->all() when you already did a ->get()
$ingeschrevenspelers = UserToernooi::with(['users' => function($query){
$query->orderBy('voornaam', 'asc');
}])->where('toernooiid', '=', $id)->get()->all();

Query relationship Eloquent

I have News model, and News has many comments, so I did this in News model:
public function comments(){
$this->hasMany('Comment', 'news_id');
}
But I also have field trashed in comments table, and I only want to select comments that are not trashed. So trashed <> 1. So I wonder is there a way to do something like this:
$news = News::find(123);
$news->comments->where('trashed', '<>', 1); //some sort of pseudo-code
Is there a way to use above method or should I just write something like this:
$comments = Comment::where('trashed', '<>', 1)
->where('news_id', '=', $news->id)
->get();
Any of these should work for you, pick the one you like the most:
Eager-loading.
$comments = News::find(123)->with(['comments' => function ($query) {
$query->where('trashed', '<>', 1);
}])->get();
You can inject the parameter to query function by use($param) method, that allows you to use dynemic query value at runtime.
Lazy-loading
$news = News::find(123);
$comments = $news->comments()->where('trashed', '<>', 1)->get();
I couldn't help but notice, though, that what you're probably trying to do is handle soft deleting, and that Laravel has built-in functionality to help you with that: http://laravel.com/docs/eloquent#soft-deleting
You can do simply in your eloquent model file.
do like this :
public function comments_with_deleted()
{
return $this->belongsTo('Comments', 'id')->where('deleted', 1);
}
public function comments()
{
return $this->belongsTo('Comments', 'id');
}
call like this :
// for show comments with deleted
$comments = News::find(123)->with('comments_with_deleted');
// for show comments without deleted
$comments = News::find(123)->with('comments');
rmobis's answer was what I needed, but it throws an error in current Laravel 5. You have to use it as an associatve array now:
$comments = News::find(123)->with(
['comments' => function ($query) {$query->where('trashed', '<>', 1);}]
);
Took me some time to figure it out, hope this will help others.
Read more in Laravel's Docs (5.6): https://laravel.com/docs/5.6/eloquent-relationships#querying-relations

Categories