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.
Related
I have a sample comments table below:
id | parent_id | post_id
1 0 1
2 0 1
3 1 1
4 2 1
5 1 1
What I am trying to achieve is to get all comments (parent_id=0) based on post_id, and count the total replies at the same time. When a query is executed it should display like the result below:
id 1 has 2 replies
id 2 has 1 reply
Here is my sample query below and it gets all comments from the given post but the problem is, I am not sure how to count at the same time in one query.
Comment::where('parent_id', '=', 0)
->where('post_id', $postId)
->get();
Does anybody know how to fix this?
You can define a method in your Comment model class.
As follows:
public function replies()
{
return $this->hasMany('App\Models\Comment','parent_id');
}
Then you can get the number of replies using the following code:
$comments = Comment::where('parent_id', '=', 0)
->where('post_id', $postId)
->withCount('replies')
->get();
In this case, you can access the number of comments with the following code:
foreach ($comments as $comment){
$countOfReplies = $comment->replies_count;
}
I hope it helps
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
}
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).
For some reason I don't get the expected result when doing the following:
$cars = Car::query();
$cars->whereIsVisible(true);
# output: $list
// [2016-01-16 09:30:04] local.INFO: array (
// 0 => 5,
// 1 => 7,
// 2 => 9,
// 3 => 3,
// )
$cars->whereHas('specifications', function($query) use ($list) {
$query->whereIn('id', ($list));
});
$cars->get();
What I expect is that I get only cars that have all the specifications that are inside that $list, but that's not correct. Even when I fill in more specifications, I get a bigger result. So there goes something wrong.
I'm used to Eloquent, so I suck in queries. But this is the Query:
select * from "cars" where "cars"."deleted_at" is null
and "is_visible" = true
and (select count(*)
from "specs" inner join "car_specs"
on "specs"."id" = "car_specs"."facility_id"
where "car_specs"."car_id" = "cars"."id"
and "id" in (5, 7, 9 ,3)) >= 1
Anyone see where it goes wrong? And how to fix it?
According to https://laravel.com/docs/5.1/eloquent-relationships#querying-relations
whereHas just checks that you have cars with the provided specifications, not that it returns those cars that match your specifications.
I think you should use where directly.
I have a multiple select:
Form::select('color', array('1' => 'Red', '2' => 'Blue', '3' => 'Green', ... ), null, array('multiple'));
How can I insert these values into a table on separate rows, like this:
id | user_id | color
----------------------------
1 | 1 | 1
2 | 1 | 2
3 | 1 | 3
4 | 1 | 4
5 | 2 | 1
6 | 2 | 3
In the above example, user with an id of 1 selected 4 different values in the select and each was inserted on a separate row.
I have this working in this way:
foreach (Input::get('tags') as $key => $value)
{
$user_color = new UserColor;
$user_color->user_id = $user->id;
$user_color->color = $key;
$user_color->save();
}
Is there a better way of doing this? It seems odd using a foreach loop when it feels like Laravel should have some sort of built-in method of inserting multiple values on multiple rows.
As Laravel doc provided,
You may also use the sync method to attach related models. The sync
method accepts an array of IDs to place on the pivot table. After this
operation is complete, only the IDs in the array will be on the
intermediate table for the model:
In this case,
$colors = Input::get('tags');
$user->colors()->sync($colors);
Please make sure to set relation in your User model :
public function colors()
{
return $this->belongsToMany('Color');
}
You can also use attach method when you parameter is not array. To more clear, Here is difference between attach and sync.