How search collection if is more then one? - laravel-5

I have datatable with a categories table.
I have two categories, Category A and Category B.
I also have a post table with post assigned to a category.
Now I can get all post and category
$posts = PostGroup::whereIn('name', ['A', 'B'])
PostGroup file has
public function posts() {
return $this->hasMany('App\Dict');
}
Ok now when I call code above and I get the following:
Collection {#301 ▼
#items: array:2 [▼
0 => PostGroup {#289 ▶}
1 => PostGroup {#302 ▶}
]
}
I can do foreach() or I can get posts
$posts = PostGroup::whereIn('name', ['A', 'B'])
$posts[0]->posts->where('group_id', 'A');
How can I avoid foreach and search the $posts collection to find group A something like:
$posts->where('group_id', 'A')->posts;

Related

Is there a way to only return the ID from this Laravel Query

I have run a query to get my specific needs but it's returning a whole bunch of array,
Is there a way to get only the specific column i needed?
This is what i am trying
$datas = DB::table('tableA')
->select('tableA.id')
->rightJoin('tableB','tableA.id','=','tableB.tableAt_id')
->where('tableB.active',1)
->whereIn('tableB.status',$myArray)
->get();
and the output is
Illuminate\Support\Collection {#1349 ▼
#items: array:221 [▼
0 => {#1327 ▼
+"id": 2020010201
}
1 => {#1346 ▼
+"id": 2020010202
}
2 => {#1343 ▼
+"id": 2020011501
}
I only want the ID. i tried toArray() but its the same
Use pluck.
Your code should be.
$datas = DB::table('tableA')
->rightJoin('tableB','tableA.id','=','tableB.tableAt_id')
->where('tableB.active',1)
->whereIn('tableB.status',$myArray)
->pluck('tableA.id');
Read More about Pluck Method

Laravel reducing relationship queries

I have two models. Expense and Method. I want to grab the sum of all expenses for each method type. I have four types:
- bank
- credit-card
- wallet
- savings
Each Expense belongsTo a Method and each Method hasMany Expenses. So it's a One-to-Many relation. So a method_id is stored for each Expense.
The following query works to get the sum of all expenses that have a method with the type bank for example:
$type = 'bank';
$expenses = auth()->user()->expenses()->with('method')->whereHas('method', function ($query) use ($type) {
$query->where('type', $type);
})->sum('amount');
But the thing is, if I want to get the total amount of all expenses for each method type, I will have to run too many queries. I would prefer just grabbing all Expenses, and then filtering through them to get the sum of all expenses for each method type.
The following for example doesn't work:
$expenses = auth()->user()->expenses()->with('method')->get();
$bank_balance = $expenses->filter(function ($expense)
{
$expense->whereHas('method', function ($query) {
$query->where('type', 'bank');
})->get(); // with or without ->get()
});
Any ideas how to get what I want by not using too many queries?
Edit:
I've unaccepted the chosen answer because it didn't give me what I needed in the end. I need to be able to do something like this in my view:
{{ $bank_balance }}
Which means, with xyz's answer, I wouldn't be able to do that, since I cannot distinguish between them. I only get results based on method_id's, but I need to be able to distinguish them by the method name.
DigitalDrifter's answer is the one that almost does the trick, but it gives me this:
Collection {#800 ▼
#items: array:3 [▼
"bank" => Collection {#797 ▼
#items: array:30 [▼
0 => array:2 [▼
"type" => "bank"
"amount" => 1536
]
1 => array:2 [▶]
2 => array:2 [▶]
3 => array:2 [▶]
4 => array:2 [▶]
5 => array:2 [▶]
]
}
"credit-card" => Collection {#798 ▶}
"wallet" => Collection {#799 ▶}
]
}
And I basically need something simple like this:
"bank" => "total sum here for all expenses that have a method of 'bank'"
"credit-card" => "total sum here for all expenses that have a method of 'credit-card'"
And so on..
I think this bit ->groupBy('type')->each->sum('amount') does the trick, but not completely. It does group by type but it does not give a sum for each type, as you can see in the collection example above.
You can group by the method id and then sum the result in a select statement.
The following is untested.
$expenses = auth()->user()
->expenses()
->select(DB::raw('SUM(amount) as total'), 'other_select_fields', ...)
->with('method')
->groupBy('method_id')
->get();
You could do this using the available collection methods:
$expenses = auth()->user()->expenses()->with('method')->get();
$groupedSums = $expenses->map(function ($expense) {
return [
'type' => $expense['method']['type'],
'amount' => $expense['method']['amount']
];
})->groupBy('type')->each->sum('amount');

View does have variables I do not pass to it

I do an ajax call and I have this code in the controller:
$menu = view('partials.nav_reserved_area', $data)->render();
return response()->json(['reserved_menu' => $menu]);
If I print $data variable before the render, this is what I get:
array:12 [▼
"request_url" => "https://www.example.com"
"theatre_events" => Collection {#515 ▼
#items: []
}
"music_events" => Collection {#498 ▼
#items: []
}
"others_events" => []
]
As You can see "theatre_events" and "music_events" are empty collection.
I do not why, but in the view, "theatre_events" and "music_events" have some items, as if it gets data from another ajax call or from another part of code.
How is it possible?
UPDATED
This should be the code incriminated (the other part of the code where maybe view gets data):
Model::whereHas('event', function ($query) {
$query
->where('end', '>=', \Carbon\Carbon::today())
->where('user_id', Auth::id())
->where('event_type', 'theatre');
})->paginate(20);

Get if user is following a page

I'm trying to get if user following or not the page. I'm trying like this:
public function get_following()
{
return $this->belongsTo(Followers::class, 'user_id')->where('type', '=', 1)->where('follower_id', '=', auth()->user()->id);
}
But this return null and I follow this page (got the item on table)...
dd($page)
Page {#305 ▼
#relations: array:3 [▼
"ptag" => Tag {#309 ▶}
"get_following" => null
"links" => Collection {#318 ▶}
]
DB:
followers.user_id = (pages.id), follower_id = (auth user), type = (1)

Get relation of relation

I'm trying to get the comments of the links with laravel relationship, the comments of links return normally, but I don't know how to get it in view or dd(), how can I do it?
Controller:
$page = Page::where('friendly_url', $id)
->select('id', 'photo', 'friendly_url', 'name', 'description', 'followers', 'links', 'tag_id', 'links_clicks')
->with('ptag', 'links', 'links.comments', 'links.tag')
->with(['links.comments.user' => function($query) {
$query->select('id', 'name', 'lastname');
}])->with(['links.comments.userProfile' => function($query) {
$query->select('id', 'photo');
}])->first();
dd($page->getRelation('links')
Collection {#301 ▼
#items: array:2 [▼
0 => Link {#307 ▼
#relations: array:2 [▼
"comments" => Collection {#316 ▼
#items: array:1 [▶]
"tag" => Tag {#322 ▶}
]
dd($page->getRelation('links')->getRelation('comments'))
BadMethodCallException
Method getRelation does not exist.
dd($page->getRelation('links')->comments)
Exception
Property [comments] does not exist on this collection instance.
EDIT:
I want to show the attributes of comment and comment.user, how I can do it?
foreach($page->getRelation('links')->pluck('comments') as $comment) {
dd($comment);
}
Collection {#327 ▼
#items: array:1 [▼
0 => Comment {#325 ▼
#attributes: array:5 [▼
"id" => 3
"content" => "teste"
"link_id" => 1
"user_id" => 1
"created_at" => "2018-01-11 00:47:32"
]
#relations: array:2 [▼
"user" => User {#330 ▼
#attributes: array:3 [▼
"id" => 1
"name" => "Halysson"
"lastname" => "Teves dos Santos"
]
}
"userProfile" => UserProfile {#326 ▶}
]
Try this-
foreach($page->links as $link){
$comments = $link->comments;
}
You should define relations first on relevent models and then using 'with' function can load models with relations OR a relation can be called directly by single model see documentation for further details
eg: you have defined a relation for user to phone, as user has a phone, one to one relation. in user model define a relation like
public function phone()
{
return $this->hasOne('App\Phone');
}
now to call this relation on user model instance.
$user = User::find(1);
dd($user->phone);
Because you're using the select() method, you also need to include all the foreign keys in it to allow Eloquent to be able to load these relationships.
But since you just start using Laravel, I'd recommend you to just remove select() method from this complex query.
If you want the links of a page :
$page->links
if you want all the comments of a page :
$page->links->pluck('comments')
that's it :)

Resources