How to get count of data based on the pivot table laravel? - laravel

I have three tables,
User cities user_cities
id name title id name user_id city_id
1 aaa designer 1 cityA 2 1
2 bbb developer 2 cityB 2 3
3 ccc designer 3 cityC 1 2
4 ddd designer 3 3
5 rrr developer 3 2
4 2
4 3
Now i am going to filter user by their title=designer. Then the filter data will be,
user
id name title
1 aaa designer
3 ccc designer
4 ddd designer
Along with this data i have to get the count of cities like this,
data: {
0: {
name:cityB,
id:2,
count:3
},
1: {
name:cityC,
id:3,
count:2
}
}
How can i get this with laravel eloquent?

You can do
$users = App\User::where('title', 'designer')->get();
and use
foreach($users as $user) {
$user->cities->count(); // collection count
}
But the better way will be Counting related models
$users = App\User::withCount('cities')->where('title', 'designer')->get();
and then
foreach($users as $user) {
$user->cities_count; // relationship count
}

Related

Check if input is in range. HASURA - GRAPHQL

I would like to check if a number is in a specific range dynamically. For example i have a table like:
id
value
age_range
1
a
3-7
2
b
7-10
3
c
3-7
4
d
0-3
if the age of the user is 5, i would like to retrieve all rows where age_range is 3-7 without writing the range in the where clause query. For example something like:
table (where: { 5 in age_range })...
Make an age_from and an age_to column if possible.
query MyQuery($int: Int!) {
table(where: {_and: [{age_to: {_gte: $int}}, {age_from: {_lte: $int}}]}) {
#Fields....
}
}

Laravel/Eloquent whereIn/where with a pair of sets

I have 3 tables in my database.
The first two tables are just normal tables with an ID and some other columns like:
Table 1
ID
col01
1
...
2
...
Table 2
ID
col01
1
...
2
...
The third table is some kind of a relation/assignment table:
Table 3
ID
table1_id
table2_id
text
1
1
1
..
2
1
2
..
3
1
3
..
4
2
1
..
5
3
3
..
Now I do have a SQL statement which does exactly what I want:
SELECT * FROM table_3 where (table1_id, table2_id) in ( (1, 1), (2, 1), (3, 3));
So Im sending following Request Body to the API:
{
"assignments": [
{
"table1_id": 1,
"table2_id": 1
},
{
"table1_id": 2,
"table2_id": 1
},
{
"table1_id": 3,
"table2_id": 3
}
]
}
I do validate my the request with
->validate($request,
[
'assignments' => 'required|array',
'assignments.*.table1_id' => 'required|integer|min:1|max:20',
'assignments.*.table2_id' => 'required|integer|min:1|max:20'
]
Now Im kinda stuck how to use the eloquent commands (e.g. whereIn) to get my desired output.
Thanks in advance!
EDIT
So I took the workaround of arcanedev-maroc mentioned here: https://github.com/laravel/ideas/issues/1021
and edited it to fit my Request.
Works like a charm.
Laravel does not provide any functions by default. The core team said that they would not maintain this feature. You can read the post here.
But you can create your own query to accomplish this. I am providing a function that you can use as per your specification:
public function test(Request $request)
{
$body=$request->input('data');
$data=json_decode($body)->assignments;
$query='(table1_id, table2_id) in (';
$param=array();
foreach($data as $datum)
{
$query=$query."(".$datum->table1_id.",".$datum->table2_id."), ";
}
$query = rtrim($query, ", ");
$query = $query.")";
$result=DB::table('table3')->whereRaw($query)->get();
return $result;
}
So I took the workaround of arcanedev-maroc mentioned here: https://github.com/laravel/ideas/issues/1021
and edited it to fit my Request.
Works like a charm.

Getting author to view correct story in laravel

I'm using Laravel 7 and I'm trying to create a site where the user can login if they have a token. I seem to have that almost working in that if you don't
have a token you can't access the page and if you put in a token that isn't in the database then it throws out an error.
The problem I'm having is that a user can still view a page they not meant to. For example I have Story 1 and Story 2, Author 1 can
view both Story 1 and 2, but Author 2 can only view Story 2.
The issue is that Author 2 can view both Story 1 and Story 2, which is wrong they only supposed to see Story 2.
I wanted to use middleware for this but I kind of hit a brick wall and not sure what next to do.
My tables
Story Table
id | title
1 | Story 1
2 | Story 2
Author Table
id | name
1 | Author 1
2 | Author 2
author_story table
id | author_id | story_id
1 | 1 | 1
2 | 1 | 2
3 | 2 | 2
My Story.php
protected $fillable = ['title'];
public function authors()
{
return $this->belongsToMany('App\Author');
}
My Author.php
protected $fillable = ['name'];
public function stories()
{
return $this->belongsToMany('App\Story');
}
My ViewStory.php (middleware)
if(Auth::check())
{
return $next($request);
}else{
abort(401);
}
Do you get any error?
I think you should use hasMany relation in my author model:
return $this->belongsToMany('App\Story',story_id, id);

How to search by laravel Eloquent Many to Many

three tables
user
id name
1 a
2 b
3 c
role
id name
1 aa
2 bb
3 cc
4 dd
role_user
role_id user_id
1 1
2 3
2 1
3 4
3 3
3 2
3 1
Laravel Code:
User::with('roles')->whereHas('roles', function($query) {
$query->whereIn('role_id', [2, 4]);
})->get();
this query return user has role 2 or 4,
I want get user has role 2 and 4;
what can I do?
To achieve what you're after you can use havingRaw():
User::with('roles')->whereHas('roles', function ($query) {
$query
->select('user_id')
->whereIn('role_id', [2, 4])
->groupBy('user_id')
->havingRaw('count(distinct(role_id))=2'); // 2 = The number of different roles i.e. count([2,4])
})->get();
When using whereIn you're essentially asking for retsults that include at least one of the values you pass to it. Using having in conjunction with group by allows you to stipulate that you want to include a certain number of them (in this case all of them).

related records of parent table in many to many relation in laravel

Table 1: categories: id,name,parent_id
id name parent_id
1 Vehicle null
2 Car 1
3 Sedan 2
Vehicle > Car > Sedan
Table 2: features: id, name
id name
1 type
2 cylinder
3 color
4 weight
Table 3: category_feature: category_id, feature_id
category_id feature_id
1 1
1 2
2 3
3 4
I could get all features by parent (category).
for example with this:
Category model:
public function features()
{
return $this->belongsToMany(Feature::class);
}
And:
$category = Category::find(1);
$features = $category->features()->get();
How can I get by a child category
all the features of the child and the features of the father's categories?
something like this:
$category = Category::find(3);
$features = $category->parent_features()->get();
I want it return these: type,cylinder,color,weight
On Categories model:
public function parent(){
return $this->belongsTo(\App\Category::class);
}
Then you can load it in one go:
$category = Category::with(['features', 'parent' => function($query){
$query->with('features');
}])->find(3);
And then you can pull the parent's features:
$features = $category->parent->features;
Or the original car's features:
$originalFeatures = $category->features;

Resources