Querying model inside 'with' - laravel

I'm making a chat api in Laravel. I have three models. User Chat and Message and they have their respective tables.
user table
id|name|email|other fields
chat table
id|user_id|receiver_id
message table
id|chat_id|message|created_at|updated_at|
Result is:
{
"data": [
{
"id": 7,
"chat_id": 5,
"message": "User 2 to 1",
"created_at": "2019-02-01 11:32:29",
"updated_at": "2019-02-01 11:32:29",
"chat": null
},
{
"id": 6,
"chat_id": 1,
"message": "Sample Chat",
"created_at": "2019-02-01 10:09:22",
"updated_at": "2019-02-01 10:09:22",
"chat": {
"id": 1,
"user_id": 1,
"receiver_id": 1,
"created_at": "2019-02-01 09:41:59",
"updated_at": "2019-02-01 10:09:22"
}
},
{
"id": 2,
"chat_id": 1,
"message": "Sample Chat",
"created_at": "2019-02-01 09:42:34",
"updated_at": "2019-02-01 09:42:34",
"chat": {
"id": 1,
"user_id": 1,
"receiver_id": 1,
"created_at": "2019-02-01 09:41:59",
"updated_at": "2019-02-01 10:09:22"
}
},
{
"id": 1,
"chat_id": 1,
"message": "Sample Chat",
"created_at": "2019-02-01 09:41:59",
"updated_at": "2019-02-01 09:41:59",
"chat": {
"id": 1,
"user_id": 1,
"receiver_id": 1,
"created_at": "2019-02-01 09:41:59",
"updated_at": "2019-02-01 10:09:22"
}
}
]
}
I've tried
$messages = Message::with(['chat' => function($query) use($user){
$query->where('user_id', $user->id);
}])
->latest()
->get();
As you can see the first data chat model is null.
I expect to only get all the messages connected to user id from the chat model.

use whereHas in your query will give only that chat belongs to purticular user.
$messages = Message::with(['chat'])->whereHas('chat', function ($query) {
$query->where('user_id', $user->id);
})
->latest()
->get();

Related

Laravel : How to randomize the query of the Quiz with choices

I'm planning to randomize the order of my query on quiz_question and choices but the quiz_question is the only one who gets randomized but the choices are still the same.
This is my code :
class QuestionByQuizID extends Controller
{
public function index(int $quiz_id){
$questions = quizQuestions::where('quiz_id', '=', $quiz_id)->with(['choices'])->inRandomOrder()->get();
if(is_null($questions)){
return response()->json('Record not found!', 401);
}
return response(['message'=>"Questions displayed successfully",
'quizQuestions'=>$questions],200);
}
}
This is the sample query using postman
"message": "Questions displayed successfully",
"quizQuestions": [
{
"id": 580,
"quiz_id": 36,
"question_num": 10,
"question_content": "What Are Those",
"correct_answer": null,
"created_by": null,
"updated_by": null,
"created_at": "2022-01-12T12:58:27.000000Z",
"updated_at": "2022-01-12T12:58:27.000000Z",
"question_image": null,
"tagalog_question": "Ano yan!",
"choices": [
{
"id": 1861,
"quiz_questions_id": 580,
"option": "choice 1",
"remarks": 0,
"created_at": "2022-01-12T12:58:27.000000Z",
"updated_at": "2022-01-12T12:58:27.000000Z",
"choices_image": null,
"tagalog_choices": "tagalog"
},
{
"id": 1862,
"quiz_questions_id": 580,
"option": "choice2",
"remarks": 0,
"created_at": "2022-01-12T12:58:27.000000Z",
"updated_at": "2022-01-12T12:58:27.000000Z",
"choices_image": null,
"tagalog_choices": "tagalog"
},
{
"id": 1863,
"quiz_questions_id": 580,
"option": "choice3",
"remarks": 0,
"created_at": "2022-01-12T12:58:27.000000Z",
"updated_at": "2022-01-12T12:58:27.000000Z",
"choices_image": null,
"tagalog_choices": "tagalog"
},
{
"id": 1864,
"quiz_questions_id": 580,
"option": "choice4",
"remarks": 1,
"created_at": "2022-01-12T12:58:27.000000Z",
"updated_at": "2022-01-12T12:58:27.000000Z",
"choices_image": null,
"tagalog_choices": "tagalog"
}
]
can anyone help me? thanks in advance.
You can do additional query conditions for the choices relationship:
$questions = quizQuestions::where('quiz_id', '=', $quiz_id)->with(['choices' => function($query){
$query->inRandomOrder();
}])->inRandomOrder()->get();
https://laravel.com/docs/8.x/eloquent-relationships#constraining-eager-loads

Laratrust show user role inside of team

I am trying to make a connection between teams and users.
Pretty much Latrust looks like an awesome package BUT some things I believe could be explained better.
Let's pick a team (say: team_id = 1):
$team = Team::where('id', $request->team_id)->first();
And let's pick our users from the team:
$roles = Role::get();
$users = User::whereRoleIs($roles->pluck('name')->toArray(), $team)->get()
This will result in the following:
{
"message": "ok",
"data": [
{
"id": 1,
"name": "niki",
"email": "niki#user.com",
"email_verified_at": null,
"created_at": "2021-07-12T11:29:09.000000Z",
"updated_at": "2021-07-12T11:29:09.000000Z",
"roles": [
{
"id": 3,
"name": "user",
"display_name": "User",
"description": "User",
"created_at": "2021-07-12T11:29:08.000000Z",
"updated_at": "2021-07-12T11:29:08.000000Z",
"pivot": {
"user_id": 1,
"role_id": 3,
"user_type": "App\\Models\\User"
}
},
{
"id": 4,
"name": "leader",
"display_name": "Leader",
"description": "Leader",
"created_at": "2021-07-12T11:29:08.000000Z",
"updated_at": "2021-07-12T11:29:08.000000Z",
"pivot": {
"user_id": 1,
"role_id": 4,
"user_type": "App\\Models\\User"
}
}
]
},
{
"id": 2,
"name": "konna",
"email": "konna#user.com",
"email_verified_at": null,
"created_at": "2021-07-12T11:29:09.000000Z",
"updated_at": "2021-07-12T11:29:09.000000Z",
"roles": [
{
"id": 3,
"name": "user",
"display_name": "User",
"description": "User",
"created_at": "2021-07-12T11:29:08.000000Z",
"updated_at": "2021-07-12T11:29:08.000000Z",
"pivot": {
"user_id": 2,
"role_id": 3,
"user_type": "App\\Models\\User"
}
},
{
"id": 3,
"name": "user",
"display_name": "User",
"description": "User",
"created_at": "2021-07-12T11:29:08.000000Z",
"updated_at": "2021-07-12T11:29:08.000000Z",
"pivot": {
"user_id": 2,
"role_id": 3,
"user_type": "App\\Models\\User"
}
}
]
}
]
}
This returns all the roles those two users have (both of them belong in the same team)
How can we pick ONLY the role that the user has inside the team?
I thought of the following:
Getting all the user records with the $users query and then picking the role of the user from there.
foreach ($users as $user){
$userArray[] = array_push($userArray, $user->name, $user->roles->first());
}
However, this will return the first() or last() role attached to the user which can be anything (especially when a user may belong to multiple teams with a different role attached to every team he attends).
So my question is, how can I show the role of a user inside a team?
I was thinking of:
$user->roles->where($team->id)
But this returns all the roles that are attached to the user and not the specific role that the user has on the team.
Any help is appreciated.
I'm not experienced in Laratrust, but i feel like i have the solution you are needing. If we explode the source code, we can see your UserTrait includes a Role relationship. Even more so, we can see that it includes the pivot for the Team model.
if (Config::get('laratrust.teams.enabled')) {
$roles->withPivot(Config::get('laratrust.foreign_keys.team'));
}
Combining that with the method wherePivot() that Laravel has, you would be able to do the following retrieving the user roles for a given team. Therefor you will retrieve all the roles if you use the condition, with the way Laratrust works, you can have multiple roles thou.
$rolesInTeam = $user->roles()->wherePivot(Config::get('laratrust.foreign_keys.team'), $team)->get();
Thank you #mrhn for your valuable input
My solution came in the following form:
$rolesInTeam[] = null;
$users = User::whereRoleIs($roles->pluck('name')->toArray(), $team)->get();
foreach ($users as $user){
$rolesInTeam[] = array_push($rolesInTeam,$user->roles()->wherePivotIn(Config::get('laratrust.foreign_keys.team'), $team)->get());
}
Which returns as a result:
null,
[
{
"id": 4,
"name": "leader",
"display_name": "Leader",
"description": "Leader",
"created_at": "2021-07-12T11:29:08.000000Z",
"updated_at": "2021-07-12T11:29:08.000000Z",
"pivot": {
"user_id": 1,
"role_id": 4,
"user_type": "App\\Models\\User"
}
}
],
2,
[
{
"id": 3,
"name": "user",
"display_name": "User",
"description": "User",
"created_at": "2021-07-12T11:29:08.000000Z",
"updated_at": "2021-07-12T11:29:08.000000Z",
"pivot": {
"user_id": 2,
"role_id": 3,
"user_type": "App\\Models\\User"
}
}
],
4,
[
{
"id": 3,
"name": "user",
"display_name": "User",
"description": "User",
"created_at": "2021-07-12T11:29:08.000000Z",
"updated_at": "2021-07-12T11:29:08.000000Z",
"pivot": {
"user_id": 5,
"role_id": 3,
"user_type": "App\\Models\\User"
}
}
],
6```

With relation if not null

I have this select but I do not know how to GET only the registers that events are not null:
$getUsers = User::where('user_id', $userId)
->with(['events' => function($query) {
$query->where('finnish', 0)
->orderBy('event_id', 'desc');
}])
->get();
With this query I get this result, where user has not meet the where condition of the relation:
{
"events": [
{
"user_id": 1,
"event_id": 1,
"created_at": null,
"updated_at": null,
"events": {
"event_id": 1,
"name": "test 1"
}
},
{
"user_id": 1,
"event_id": 25,
"created_at": null,
"updated_at": null,
"events": null
},
{
"user_id": 1,
"event_id": 34,
"created_at": null,
"updated_at": null,
"events": null
}
]
}
And I only like this:
{
"events": [
{
"user_id": 1,
"event_id": 1,
"created_at": null,
"updated_at": null,
"events": {
"event_id": 1,
"name": "test 1"
}
]
}
Thanks
You can query relationship existence using ->has('events').
And if you want extra filters, there is whereHas.
$getUsers = User::where('user_id', $userId)
->whereHas('events', function function($query) {
$query->where('finnish', 0);
}
->with(['events' => function($query) {
$query->where('finnish', 0)
->orderBy('event_id', 'desc');
}])
->get();

Laravel eloquent and query builder Eager Loading Multiple Relationships with where clause

I have few tables, they are room_types, rooms, rates, prices I want to get
room_types with rooms with rates and rates with prices where(price room_type_id = room_types.id) . I tried to do something like that
$roomTypeIds = [];
foreach ($hotel->rooms as $room) {
array_push($roomTypeIds, $room->roomtype->id);
}
$roomsByType = RoomType::with(['rooms' => function ($query) {
$query->with(['rates' => function($q) {
$q->with('policy', 'prices');
}]);
}])->whereIn('id', array_unique($roomTypeIds))->get();
but in this example Im getting all prices but I want to get only that prices which room_type_id IS EQUAL TO current room_type.id. So for that I have tried to do some think like this
$roomsByType = RoomType::with(['rooms' => function ($query) {
$query->with(['rates' => function($q) {
$q->with(['policy', 'prices' => function($q1) {
$q1->where('room_type_id', '');
}]);
}]);
}])->whereIn('id', array_unique($roomTypeIds))->get();
But I don't know what to put in where clouse. So are there any way to do this?
And result that I want to have is
[
{
"id": 2,
"name": "Twin/Double",
"created_at": "2017-12-11 08:56:16",
"updated_at": "2017-12-11 08:56:16",
"rooms": [
{
"id": 4,
"hotel_id": 1,
"room_type_id": 2,
"custom_name": null,
"room_name": "3",
"number_of_type": 2,
"number_of_bedrooms": null,
"number_of_livingrooms": null,
"number_of_bathrooms": null,
"created_at": "2017-12-12 06:37:34",
"updated_at": "2017-12-12 06:37:34",
"rates": [
{
"id": 4,
"user_id": 19,
"custom_name": "Default rate",
"price": 0,
"automatic": 0,
"rate_id": null,
"operand": null,
"amount": null,
"currency": null,
"policy_id": 1,
"meal_types": null,
"created_at": "2017-12-12 09:27:31",
"updated_at": "2017-12-12 09:27:29",
"pivot": {
"room_id": 4,
"rate_id": 4
},
"policy": {
"id": 1,
"name": "Free cancellation before 3 / 60 %",
"hotel_id": 1,
"free": 1,
"before_day": 3,
"before_day_price": 60,
"until_day_price": null,
"created_at": "2017-12-08 14:03:31",
"updated_at": "2017-12-08 14:03:31"
},
"prices": [
{
"id": 1,
"rate_id": 4,
"room_type_id": 2,
"from": "2017-12-01 09:18:46",
"to": "2017-12-18 09:18:57",
"amount": 100,
"created_at": "2017-12-18 09:19:11",
"updated_at": "2017-12-18 09:19:12"
},
{
"id": 3,
"rate_id": 4,
"room_type_id": 3,
"from": "2017-12-22 10:36:30",
"to": "2017-12-30 10:36:35",
"amount": 3000,
"created_at": null,
"updated_at": null
}
]
}
]
},
{
"id": 5,
"hotel_id": 1,
"room_type_id": 2,
"custom_name": null,
"room_name": "3",
"number_of_type": 2,
"number_of_bedrooms": null,
"number_of_livingrooms": null,
"number_of_bathrooms": null,
"created_at": "2017-12-12 06:37:34",
"updated_at": "2017-12-12 06:37:34",
"rates": [
{
"id": 4,
"user_id": 19,
"custom_name": "Default rate",
"price": 0,
"automatic": 0,
"rate_id": null,
"operand": null,
"amount": null,
"currency": null,
"policy_id": 1,
"meal_types": null,
"created_at": "2017-12-12 09:27:31",
"updated_at": "2017-12-12 09:27:29",
"pivot": {
"room_id": 5,
"rate_id": 4
},
"policy": {
"id": 1,
"name": "Free cancellation before 3 / 60 %",
"hotel_id": 1,
"free": 1,
"before_day": 3,
"before_day_price": 60,
"until_day_price": null,
"created_at": "2017-12-08 14:03:31",
"updated_at": "2017-12-08 14:03:31"
},
"prices": [
{
"id": 1,
"rate_id": 4,
"room_type_id": 2,
"from": "2017-12-01 09:18:46",
"to": "2017-12-18 09:18:57",
"amount": 100,
"created_at": "2017-12-18 09:19:11",
"updated_at": "2017-12-18 09:19:12"
},
{
"id": 3,
"rate_id": 4,
"room_type_id": 3,
"from": "2017-12-22 10:36:30",
"to": "2017-12-30 10:36:35",
"amount": 3000,
"created_at": null,
"updated_at": null
}
]
}
]
}
]
}
]
Look at the whereHas function instead of using with
https://laravel.com/docs/5.5/eloquent-relationships#querying-relations

Laravel 5.0 Eloquent Need query to list user, posts and related comments in facebook style

My table's fields are as below :
users : id email first_name last_name (rest are there but need only these)
activity_stream : id user_id post created_at updated_at deleted_at
activity_stream_comments : id post_id user_id comment created_at updated_at deleted_at
I need listing of all the users posts with related comments just like you see in facebook, it shows various users posts with posts comments so for now I basically need to list down all the users posts with related comments.
I am trying the below query but it gives only the post that have comments that too in different sets :
$results = DB::table('activity_stream')
->join('users', 'users.id', '=', 'activity_stream.user_id')
->join('activity_stream_comments', 'activity_stream.id', '=', 'activity_stream_comments.post_id')
->select('activity_stream.*', 'users.first_name','users.last_name', 'activity_stream_comments.comment')
/*->where('activity_stream.user_id', $user_id)*/
->whereNull('activity_stream.deleted_at')
->orderBy('activity_stream.created_at', 'desc')
->get();
return response()->json($results);
And the return is :
[
{
"id": "97",
"user_id": "30",
"post": "hi how are you?",
"created_at": "2015-11-20 04:35:11",
"updated_at": "2015-11-20 04:35:11",
"deleted_at": null,
"first_name": "Abhijan",
"last_name": "Pal",
"comment": "test"
},
{
"id": "14",
"user_id": "49",
"post": "Test Post",
"created_at": "2015-11-13 04:51:53",
"updated_at": "2015-11-13 04:51:53",
"deleted_at": null,
"first_name": "Nazir",
"last_name": "Hussain",
"comment": "This is my first comment"
},
{
"id": "14",
"user_id": "49",
"post": "Test Post",
"created_at": "2015-11-13 04:51:53",
"updated_at": "2015-11-13 04:51:53",
"deleted_at": null,
"first_name": "Nazir",
"last_name": "Hussain",
"comment": "This is my 2nd comment"
}
]
Improvement :
$results = User::with('activity_stream.activity_stream_comments')->find($user_id);
return response()->json($results);
While using relationship and using above query I get the response as below :
{
"id": "49",
"email": "nazir.2cool#gmail.com",
"permissions": null,
"last_login": "2015-11-19 09:32:36",
"first_name": "Nazir",
"last_name": "Hussain",
"created_at": "2015-11-03 12:36:56",
"updated_at": "2015-11-19 09:32:36",
"facebook_id": "1051400994880427",
"facebook_token": "CAAX3UySfMDcBAFs8glgjz9p1Qdt0M1zwRrmZB9y4WkEPOEldIM5BKVURut8pcg9ios6GiZBschXWBKCqM6HdyZCIxkih6Rwh2SSABrzAHZCzGZBqcISDIlUwnNp73zF8PEZAgXKdzhZAQtfjZAeawUlAHTNpt2RyXTPoeH0ETj8jSclIxMSXPxfbDlnmNjoJXVwZD",
"facebook_profile_url": "",
"facebook_avatar": "https://graph.facebook.com/v2.5/1051400994880427/picture?width=1920",
"google_id": "112519651577038840839",
"google_token": "ya29.MQLD4wmUQSqGyMVENv8mrko-tvsqg3aLibdy5m-KWBp-HqP5liYB8GlWvSC4c1ZXka3YRRgA2dX40Q",
"google_profile_url": "https://plus.google.com/+NazirHussain91",
"google_avatar": "https://lh3.googleusercontent.com/-nLaXbUtBV0g/AAAAAAAAAAI/AAAAAAAAAAA/QaM3CzCJxlM/photo.jpg?sz=50",
"twitter_id": "832857385",
"twitter_token": "832857385-2PqAa48RffL2Yl7ZNJinBhIawMmH56amI54OBklR",
"twitter_profile_url": "",
"twitter_avatar": "http://pbs.twimg.com/profile_images/2626032008/hzd0ynsei7qjpyobaklw.jpeg",
"role": "author",
"activity_stream": [
{
"id": "14",
"user_id": "49",
"post": "Test Post",
"created_at": "2015-11-13 04:51:53",
"updated_at": "2015-11-13 04:51:53",
"deleted_at": null,
"activity_stream_comments": [
{
"id": "1",
"post_id": "14",
"user_id": "49",
"comment": "This is my first comment",
"created_at": "2015-11-19 10:49:13",
"updated_at": "2015-11-19 10:49:13",
"deleted_at": null
},
{
"id": "2",
"post_id": "14",
"user_id": "49",
"comment": "This is my second comment that I edited as well",
"created_at": "2015-11-19 11:03:01",
"updated_at": "2015-11-20 11:35:04",
"deleted_at": null
},
{
"id": "6",
"post_id": "14",
"user_id": "30",
"comment": "This is another test comment",
"created_at": "-0001-11-30 00:00:00",
"updated_at": "-0001-11-30 00:00:00",
"deleted_at": null
}
]
},
{
"id": "24",
"user_id": "49",
"post": "This is my first post",
"created_at": "2015-11-13 06:23:24",
"updated_at": "2015-11-13 06:23:24",
"deleted_at": null,
"activity_stream_comments": []
}
]
}
Now there are two questions : 1. How to use orderBy and 2. In the post and comment level how to get user name along with user id at the same time because querying again is not at all a good idea.

Resources