laravel relation with only get second relation - php

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');

Related

how to group by the relation entity in laravel

i have 2 models order and city and each order has one city now what i want to do is to show the user how many orders per each city he has . and the result for example would be some thing like below :
Illuminate\Support\Collection {#2220 ▼
#items: array:17 [▼
"new-york" => 80
"city-number2" => 20
"city-number3" => 10
"city-number4" => 5
]
}
what i have tried so far is to work with the laravels withcount on order like below :
$orders = Order::withCount('orders')->where('shop_id', $shop->id)->get();
but no luck with it because it returns the count of all cities not each city individually .
thanks in advance
You can do this query from the other direction easily:
$cities = City::withCount(['orders' => fn ($q) => $q->where('shop_id', $shop->id)])->get();
foreach ($cities as $city) {
echo "{$city->name}: {$city->orders_count}";
}
If you need to restrict which cities are listed you can constrain that further if needed.
this problem is based on one to many relationships in DBMS, in laravel there is an inbuild option that comes with eloqut (one city has many orders and one order belongs to one city)
first of all, you need to implement the cities model and order model
inside cities model define a function like this
public function orders()
{
return $this->belongsTo(Order::class, 'city_id');
}
and in order model define a function like this
public function city()
{
return $this->hasMany(City::class, 'order_id');
}
then in the controller to find how many orders per each city use the query like this with laravel eloquent
$cities= City::withCount(['orders' => fn ($q) => $q->where('shop_id', $shop->id)])->get();
foreach ($cities as $city) {
echo $city->orders_count;
}
The withCount method which will place a {relation}_count attribute on the resulting models:
the controller to find how many orders per each city use the query like this with laravel eloquent.
$orders = Order::with('cities')
->select('city_id',\DB::raw('count(*) as city'))
->groupby('city_id')
->get();

Eloquent limit relationship fields

I have the following relationships:
TheEpisodeJob hasOne TheEpisode
TheEpisodeJob hasMany TheJobs
I am successfuly retrieving all TheEpisodesJobs and TheSeriesEpisodes with all the fields in database (including sensitive information) using this command:
$jobs = TheEpisodeJob::with('TheEpisode')->get();
I would like to limit TheEpisode fields shown only for this case (public $hidden will not work)
EDIT
Let's say I need only title and description field from TheEpisode.
How can I achieve that?
As #Buglinjo pointed out you can scope the relationship when eager loading, however, if you're going to be doing this to only select specific columns you must included the related column in the select so that Eloquent knows which Model to attach the related data to.
This should give you what you want:
$jobs = TheEpisodeJob::with(['TheEpisode' => function ($query) {
$query->select('jobID', 'title', 'description');
}])->get();
Furthermore, if you then wanted to to get rid of the jobID as well you could do something like:
$jobs->transform(function ($job) {
$job->TheEpisode->transform(function ($item) {
unset($item->jobID);
return $item;
});
return $job;
});
Hope this helps!
As far as I understood you, you want to limit the results according to some more parameters. If I am right, you should add more queries, like:
->where, ->orwhere, ->select, ->whereNull
Here is the link for more queries. Hope it will help )
I saw an update, so then you need
->pluck('title', 'description');
for more information, go to the link above
You should do like this:
$jobs = TheEpisodeJob::with(['TheEpisode' => function($q){
$q->get(['title', 'description']);
//or
$q->pluck('title', 'description');
}])->get();
Note: pluck is getting as array not as Eloquent Object.

Laravel pluck fields from relations

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');
}
}

Transform specific fields in Laravel?

How do I Transform specific fields in Laravel?
For example:
$user = \Auth::User();
return [
'user_id' => $user->id,
'articles' => $user->articles,
'pages' => $user->pages,
];
$user->articles will show the entries the articles table and $user->pages from the pages table.
In the User model, it would be defined something like that:
public function articles()
{
return $this->hasMany(Article::class);
}
I do not want to return all the fields from $user->articles, just id, name, and description. What is good way to transform this collection?
I would like to do something like:
'articles' => transformArticle($user->articles),
In the relationship:
return $this->hasMany('Article::class')->select(array('id', 'name','description'));
Or whenever you need it:
User::with(array('articles'=>function($query){
$query->select('id','name','description');
}))->get();
Transformers
maybe you need this.

get count in relation table in yii2 Activerecord

I have two table for post and user. I want to show post count of user in users list gridview. In yii 1 I use this in model to define a relation for this purpose:
'postCount' => array(self::STAT, 'Post', 'author',
'condition' => 'status = ' . Post::ACTIVE),
...
User:find...().with('postCount').....
But i don't know how to implement this in Yii2 to get count of post in User:find():with('...') to show in gridview.
Anyone try this in yii2?
Here is an example of what I did and it seems to work fine so far. It was used to get a count of comments on a post. I simply used a standard active record count and created the relation with the where statement using $this->id and the primary key of the entry its getting a count for.
public function getComment_count()
{
return Comment::find()->where(['post' => $this->id])->count();
}
Just a passing it along...
You can try the code below:
User::find()->joinWith('posts',true,'RIGHT JOIN')->where(['user.id'=>'posts.id'])->count();
Or if you want to specify a user count:
//user id 2 for example
User::find()->joinWith('posts',true,'RIGHT JOIN')->where(['user.id'=>'posts.id','user.id'=>2])->count();
Please note that, posts is a relation defined in your User model like below:
public function getPosts()
{
return $this->hasMany(Post::className(), ['user_id' => 'id']);
}
Well still I think for those who it may concern, if you JUST want the count a select and not the data it will be better use this instead imho:
$count = (new \yii\db\Query())
->select('count(*)')
->from('table')
->where(['condition'=>'value'])
->scalar();
echo $count;

Categories