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

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

Related

Issue trying to assert Response structure based on type

Laravel Version: 6.20.30
PHP Version: 7.2.8
Database Driver & Version: Mysql 5.7
Description:
The issue I'm facing is that I need to test the structure of a response in which some properties are look-alike
Steps To Reproduce:
this is the response to test against :
[
{
"id": 1,
"product_id": 1,
"section_id": 1,
"image_id": null,
"html_id": 1,
"index": 0,
"name": "zip_2MB",
"description": "Error ex sed numquam et odit minima quia sunt. Praesentium in ea numquam. Alias ut pariatur voluptates modi velit veniam aspernatur accusantium. Aut facilis minus reprehenderit praesentium eum.",
"title": "Slide #53",
"backup": false,
"required": true,
"emailable": 0,
"type": 0,
"asset_id": null,
"thumb_id": null,
"image": null,
"html": {
"id": 1,
"product_id": 1,
"zip_id": 1,
"thumb_id": 1,
"name": "zip_2MB",
"rank": 0,
"created_at": "2021-08-11 13:24:42",
"updated_at": "2021-08-11 13:24:42",
"deleted_at": null,
"thumb": {
"id": 1,
"user_id": null,
"key": "archive/zip_2MB.zip",
"bucket": "symmetryk-assets-testing",
"region": "eu-west-2",
"cdnURL": "https://symmetryk-assets-testing.s3.eu-west-2.amazonaws.com/archive/zip_2MB.zip",
"size": 2036861,
"size_thumb": 0,
"size_preview": 0,
"mime_type": "application/zip",
"extension": "zip",
"width": null,
"height": null,
"duration": null,
"viewed": null,
"created_at": "2021-08-11 13:24:42",
"updated_at": "2021-08-11 13:24:42",
"deleted_at": null
},
"html": {
"id": 1,
"user_id": null,
"key": "archive/zip_2MB.zip",
"bucket": "symmetryk-assets-testing",
"region": "eu-west-2",
"cdnURL": "https://symmetryk-assets-testing.s3.eu-west-2.amazonaws.com/archive/zip_2MB.zip",
"size": 2036861,
"size_thumb": 0,
"size_preview": 0,
"mime_type": "application/zip",
"extension": "zip",
"width": null,
"height": null,
"duration": null,
"viewed": null,
"created_at": "2021-08-11 13:24:42",
"updated_at": "2021-08-11 13:24:42",
"deleted_at": null
}
}
},
{
"id": 2,
"product_id": 1,
"section_id": 1,
"image_id": 2,
"html_id": null,
"index": 1,
"name": "file_example_JPG_500kB",
"description": "Et voluptatem et corporis in.",
"title": "Slide #78",
"backup": false,
"required": false,
"emailable": 0,
"type": 2,
"asset_id": 2,
"thumb_id": 2,
"image": {
"id": 2,
"product_id": 1,
"image_id": 2,
"thumb_id": 2,
"name": "file_example_JPG_500kB",
"rank": 1,
"created_at": "2021-08-11 13:25:23",
"updated_at": "2021-08-11 13:25:23",
"deleted_at": null,
"thumb": {
"id": 2,
"user_id": null,
"key": "image/file_example_JPG_500kB.jpeg",
"bucket": "symmetryk-assets-testing",
"region": "eu-west-2",
"cdnURL": "https://symmetryk-assets-testing.s3.eu-west-2.amazonaws.com/image/file_example_JPG_500kB.jpeg",
"size": 555181,
"size_thumb": 0,
"size_preview": 0,
"mime_type": "image/jpeg",
"extension": "jpeg",
"width": null,
"height": null,
"duration": null,
"viewed": null,
"created_at": "2021-08-11 13:25:23",
"updated_at": "2021-08-11 13:25:23",
"deleted_at": null
},
"image": {
"id": 2,
"user_id": null,
"key": "image/file_example_JPG_500kB.jpeg",
"bucket": "symmetryk-assets-testing",
"region": "eu-west-2",
"cdnURL": "https://symmetryk-assets-testing.s3.eu-west-2.amazonaws.com/image/file_example_JPG_500kB.jpeg",
"size": 555181,
"size_thumb": 0,
"size_preview": 0,
"mime_type": "image/jpeg",
"extension": "jpeg",
"width": null,
"height": null,
"duration": null,
"viewed": null,
"created_at": "2021-08-11 13:25:23",
"updated_at": "2021-08-11 13:25:23",
"deleted_at": null
}
},
"html": null
}
]
this is can be returned from a route for easy testing.
$request = $this->get('/dummy-url-to-return-the-response');
$request
->assertJsonStructure(
[
'*' => [
'id',
'product_id',
'section_id',
'image_id',
'html_id',
'index',
'name',
'description',
'title',
'backup',
'required',
'emailable',
'type',
'asset_id',
'thumb_id',
'image' => [
'*' => [
'id',
'product_id',
'image',
'thumb'
]
],
'html' => [
'*' => [
'id',
'product_id',
'image',
'thumb'
]
]
]
]
)
If an object have an html object, the image object is null and vis versa.
Keep in mind that the structure was truncated for easier follow so assuming that I am writing this correctly, this is the message I keep getting.
Argument #2 of PHPUnit\Framework\Assert::assertArrayHasKey() must be an array or ArrayAccess

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

Querying model inside 'with'

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

Laravel apply sortBy to a related models collection

I am using the below code:
$greatDeals = $greatDealsinitial->sortBy(function ($deal, $key) {
return $deal->hotel->room[0]->price;
});
Here room is an array, I want to sort this collection by price in the room array.
But I can't use return $row->hotel->room->price;
So how can I sort this?
my collection :
[
{
"id": 2,
"hotel_id": 1,
"deal_code": "sfg",
"date": "2018-04-13 00:00:00",
"discount": 12,
"status": 1,
"created_at": "2018-04-13 11:21:18",
"updated_at": "2018-04-13 11:21:18",
"deleted_at": null,
"client_id": 1,
"hotel": {
"id": 1,
"name": "Aloft Dongguan Songshan Lake",
"address": "Dongguan, China, 511700",
"phone": "76982106666",
"country": "101",
"country_name": "India",
"state": "35",
"state_name": "Tamil Nadu",
"city": "3551",
"city_name": "Abiramam",
"area": null,
"pincode": "511700",
"nearest_airport": null,
"nearest_railway": null,
"star": null,
"check_in": null,
"check_out": null,
"lat": "22.929869",
"lng": "113.89232800000002",
"description": null,
"astatus": "1",
"status": "0",
"created_at": "2018-04-13 10:27:30",
"updated_at": "2018-04-13 10:27:48",
"client_id": 1,
"hotel_age": null,
"hotel_privilege": "asdf",
"departure": "sdaf",
"checkout_fee": "asdf",
"book_policy": "sadf",
"hotel_secured": null,
"hotel_pets": null,
"hotel_other": null,
"room": [
{
"id": 3,
"roomtype_id": 2,
"room_count": null,
"max_adult": 2,
"max_children": 1,
"capacity": 3,
"room_number": null,
"floor": null,
"number": null,
"name": null,
"city_name": "Abiramam",
"city": 3551,
"price": "200.00",
"extra_bed_price": null,
"astatus": "1",
"status": "0",
"created_at": "2018-04-13 12:37:11",
"updated_at": "2018-04-13 12:37:52",
"deleted_at": null,
"client_id": 1,
"hotel_id": 1
},
{
"id": 1,
"roomtype_id": 1,
"room_count": null,
"max_adult": 2,
"max_children": 1,
"capacity": 3,
"room_number": null,
"floor": null,
"number": null,
"name": null,
"city_name": "Abiramam",
"city": 3551,
"price": "435.00",
"extra_bed_price": null,
"astatus": "1",
"status": "0",
"created_at": "2018-04-13 10:33:24",
"updated_at": "2018-04-13 11:21:38",
"deleted_at": null,
"client_id": 1,
"hotel_id": 1
}
]
}
},
{
"id": 4,
"hotel_id": 2,
"deal_code": "ertgerf",
"date": "2018-04-13 00:00:00",
"discount": 1,
"status": 1,
"created_at": "2018-04-13 11:47:39",
"updated_at": "2018-04-13 11:53:45",
"deleted_at": null,
"client_id": 2,
"hotel": {
"id": 2,
"name": "Temperance Lane",
"address": "Temperance Ln, Sydney NSW 2000, Australia",
"phone": "9842814927",
"country": "14",
"country_name": "Austria",
"state": "281",
"state_name": "Carinthia",
"city": "6843",
"city_name": "Maria Rain",
"area": "test",
"pincode": "2000",
"nearest_airport": "demo",
"nearest_railway": "test",
"star": null,
"check_in": "09:30 AM",
"check_out": "04:30 PM",
"lat": "-33.86963590000001",
"lng": "151.20667979999996",
"description": "test description",
"astatus": "1",
"status": "0",
"created_at": "2018-04-13 10:43:16",
"updated_at": "2018-04-13 11:41:25",
"client_id": 2,
"hotel_age": null,
"hotel_privilege": "testtesttesttesttesttesttesttesttesttesttest",
"departure": "testtesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttest",
"checkout_fee": "testtesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttest",
"book_policy": "testtesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttest",
"hotel_secured": null,
"hotel_pets": null,
"hotel_other": "testtesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttest",
"room": [
{
"id": 2,
"roomtype_id": 1,
"room_count": null,
"max_adult": 2,
"max_children": 3,
"capacity": 5,
"room_number": null,
"floor": null,
"number": null,
"name": null,
"city_name": "Maria Rain",
"city": 6843,
"price": "345.00",
"extra_bed_price": null,
"astatus": "1",
"status": "0",
"created_at": "2018-04-13 10:46:04",
"updated_at": "2018-04-13 10:47:05",
"deleted_at": null,
"client_id": 2,
"hotel_id": 2
}
]
}
}
]
This sorts the rooms of each hotel per price:
$greatDealsinitial->each(function($deal) {
$deal->hotel->setRelation('room', $deal->hotel->room->sortBy('price'));
});
$greatDeals = $greatDealsinitial->hotel->room->sortBy('price')
if this array looks
[
['price' => 0],
['price' => 1],
['price' => 3]
]

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

Resources