How produces statistics with laravel? - mysql

I work on a laravel application that is a bit like a quiz. You create an exercise, you add questions and each question to answers.
Until then everything is fine.
My interest is to present statistics for each exercise after schoolchildren have answered the tests.
I want to be able to display the answer percentage for each question.
Here is an example of the data structure I have:
[
{
"id": 1,
"exercice_id": 1,
"question": "Lorem ipsum ?",
"responses": [
{
"id": 1,
"exercice_id": 1,
"question_id": 1,
"response_text": "Yes",
},
{
"id": 2,
"exercice_id": 1,
"question_id": 1,
"response_text": "No",
}
],
"choice": [
{
"id": 1,
"exercice_id": 1,
"question_id": 1,
"response_id": 1,
},
{
"id": 2,
"exercice_id": 1,
"question_id": 1,
"response_id": 1,
},
{
"id": 3,
"exercice_id": 1,
"question_id": 1,
"response_id": 2,
}
]
},
{
"id": 2,
"exercice_id": 1,
"question": "fake text ?",
"responses": [
{
"id": 3,
"exercice_id": 1,
"question_id": 2,
"response_text": "A",
},
{
"id": 4,
"exercice_id": 1,
"question_id": 2,
"response_text": "B",
},
{
"id": 5,
"exercice_id": 1,
"question_id": 2,
"response_text": "C",
}
],
"choice": [
{
"id": 4,
"exercice_id": 1,
"question_id": 2,
"response_id": 5,
},
{
"id": 5,
"exercice_id": 1,
"question_id": 2,
"response_id": 3,
}
]
}
]
I tried the groupBy method on several elements. but I have not found the formula yet.
return response()->json(Question::with('responses','choice')
->where('exercice_id',$exo->id)
//->groupBy('choice')
->get(),
200,[], JSON_NUMERIC_CHECK);

Related

OData filter on array property to return empty array or array

I have a JSON object similar to this one:
{
"customers": [
{
"id": 1,
"name": "bob",
"orders": [{"id": 1, "customerId": 1, "itemId": 6}]
},
{
"id": 2,
"name": "jane",
"orders": [{"id": 2, "customerId": 2, "itemId": 7}]
}
]
}
I'd like to query it like....
...odata/customers?$expand=orders&$filter=orders/any(order: order/itemId eq 6)
...and get...
{
"customers": [
{
"id": 1,
"name": "bob",
"orders": [{"id": 1, "customerId": 1, "itemId": 6}]
},
{
"id": 2,
"name": "jane",
"orders": []
}
]
}
but what I get is...
{
"customers": [
{
"id": 1,
"name": "bob",
"orders": [{"id": 1, "customerId": 1, "itemId": 6}]
}
]
}
I want to get all the customers and I only want the filter to apply to the "orders".
What can I do to get this result?
Just got the same problem!
Solved by filtering my expand by the same condition in any().
applications?$expand=accounts($filter=idUser eq 5)&$filter=accounts/any(account: account/idUser eq 5)
Maybe to late but hope it will help someone else ;)

lumen order by with two level relation

this is a task manager web app
i have 3 tables rows, tasks and inputs
the inputs table has order column to choice which column to be shown first
row has many tasks
input has many tasks
so every task has an input and a row
i want to sort the tasks by row_id and then by input.order
first try
App\Row::with(['user', 'tasks', 'tasks.option', 'tasks.input'])
->orderBy('rows.id', 'ASC', 'order', 'ASC')
->get();
it ignores the order
result
[
{
"id": 1,
"user_id": 1,
"created_at": "2018-06-07 18:40:23",
"updated_at": "2018-06-07 18:40:23",
"tasks": [
{
"id": 1,
"row_id": 1,
"input_id": 1,
"option_id": 1,
"value": null,
"input": {
"id": 1,
"name": "assigned to",
"type": 1,
"value": "mario",
"required": 1,
"order": 2,
"user_id": 1,
"created_at": "2018-06-07 18:40:16",
"updated_at": "2018-06-08 10:08:19"
}
},
{
"id": 2,
"row_id": 1,
"input_id": 2,
"option_id": null,
"value": "test new option",
"input": {
"id": 2,
"name": "test new option",
"type": 0,
"value": "test new option",
"required": 0,
"order": 3,
"user_id": 1,
"created_at": "2018-06-07 18:40:44",
"updated_at": "2018-06-08 10:08:19"
}
},
{
"id": 3,
"row_id": 1,
"input_id": 3,
"option_id": null,
"value": "2018-07-01",
"input": {
"id": 3,
"name": "deadline",
"type": 3,
"value": "2018-07-01",
"required": 0,
"order": 4,
"user_id": 1,
"created_at": "2018-06-08 10:07:37",
"updated_at": "2018-06-08 10:08:19"
}
},
{
"id": 4,
"row_id": 1,
"input_id": 4,
"option_id": null,
"value": "",
"input": {
"id": 4,
"name": "priority",
"type": 6,
"value": "",
"required": 0,
"order": 1,
"user_id": 1,
"created_at": "2018-06-08 10:08:19",
"updated_at": "2018-06-08 10:08:19"
}
}
]
}
]
second try
App\Row::with(['user', 'tasks', 'tasks.option', 'tasks.input'])
->orderBy('rows.id', 'ASC')
->orderBy('order', 'ASC')
->get();
but it generated an error
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'order' in 'order clause' (SQL: select * from `rows` order by `rows`.`id` asc, `order` asc)
third try
App\Row::with([
'user',
'tasks',
'tasks.option',
'tasks.input' =>
function($query) {
$query->orderBy('order', 'ASC');
}
])
->orderBy('rows.id', 'ASC')
->get();
it ignores the order result same as first
forth try
return App\Row::with(['user', 'tasks', 'tasks.option', 'tasks.input'])
->join('tasks', 'rows.id', '=', 'tasks.row_id')
->join('inputs', 'inputs.id', '=', 'tasks.input_id')
->orderBy('rows.id', 'ASC')
->orderBy( 'inputs.order', 'ASC')
->get();
it generate row for every column and not row as it suppose to
result
[
{
"id": 4,
"user_id": 1,
"created_at": "2018-06-08 10:08:19",
"updated_at": "2018-06-08 10:08:19",
"row_id": 1,
"input_id": 4,
"option_id": null,
"value": "",
"name": "priority",
"type": 6,
"required": 0,
"order": 1,
"tasks": []
},
{
"id": 1,
"user_id": 1,
"created_at": "2018-06-07 18:40:16",
"updated_at": "2018-06-08 10:08:19",
"row_id": 1,
"input_id": 1,
"option_id": 1,
"value": "mario",
"name": "assigned to",
"type": 1,
"required": 1,
"order": 2,
"tasks": [
{
"id": 1,
"row_id": 1,
"input_id": 1,
"option_id": 1,
"value": null,
"input": {
"id": 1,
"name": "assigned to",
"type": 1,
"value": "mario",
"required": 1,
"order": 2,
"user_id": 1,
"created_at": "2018-06-07 18:40:16",
"updated_at": "2018-06-08 10:08:19"
}
},
{
"id": 2,
"row_id": 1,
"input_id": 2,
"option_id": null,
"value": "test new option",
"input": {
"id": 2,
"name": "test new option",
"type": 0,
"value": "test new option",
"required": 0,
"order": 3,
"user_id": 1,
"created_at": "2018-06-07 18:40:44",
"updated_at": "2018-06-08 10:08:19"
}
},
{
"id": 3,
"row_id": 1,
"input_id": 3,
"option_id": null,
"value": "2018-07-01",
"input": {
"id": 3,
"name": "deadline",
"type": 3,
"value": "2018-07-01",
"required": 0,
"order": 4,
"user_id": 1,
"created_at": "2018-06-08 10:07:37",
"updated_at": "2018-06-08 10:08:19"
}
},
{
"id": 4,
"row_id": 1,
"input_id": 4,
"option_id": null,
"value": "",
"input": {
"id": 4,
"name": "priority",
"type": 6,
"value": "",
"required": 0,
"order": 1,
"user_id": 1,
"created_at": "2018-06-08 10:08:19",
"updated_at": "2018-06-08 10:08:19"
}
}
]
},
{
"id": 2,
"user_id": 1,
"created_at": "2018-06-07 18:40:44",
"updated_at": "2018-06-08 10:08:19",
"row_id": 1,
"input_id": 2,
"option_id": null,
"value": "test new option",
"name": "test new option",
"type": 0,
"required": 0,
"order": 3,
"tasks": []
},
{
"id": 3,
"user_id": 1,
"created_at": "2018-06-08 10:07:37",
"updated_at": "2018-06-08 10:08:19",
"row_id": 1,
"input_id": 3,
"option_id": null,
"value": "2018-07-01",
"name": "deadline",
"type": 3,
"required": 0,
"order": 4,
"tasks": []
}
]
this file is here
the full code is here
Because it searches columns in table rows not in input.
App\Row::with(['user', 'tasks', 'tasks.option', 'tasks.input'=> function ($q){
$q->orderBy('order', 'ASC'); // order from "rows" table
}])
->orderBy('id', 'ASC') // id from "rows" table
->get();

Laravel pagination json format

I am using laravel database pagination for an api. It gives the output as follows :
{
"current_page": 1,
"data": [
{
"id": 1,
"name": "Default"
},
{
"id": 2,
"name": "Default without Sidebar"
}
],
"first_page_url": "http://example.com/api/layouts?a=1",
"from": 1,
"last_page": 1,
"last_page_url": "http://example.com/api/layouts?a=1",
"next_page_url": null,
"path": "http://example.com/api/layouts",
"per_page": 10,
"prev_page_url": null,
"to": 2,
"total": 2
}
I don't want or need first_page_url, last_page_url, etc, so it should just be:
{
"current_page": 1,
"data": [
{
"id": 1,
"name": "Default"
},
{
"id": 2,
"name": "Default without Sidebar"
}
],
"from": 1,
"last_page": 1,
"to": 2,
"total": 2
}
So, Is there a way, to format the output json so that i can remove or hide some extra info which i don't need .
You can do something like this:
$except = ['first_page_url', 'last_page_url'];
return array_except(<YourModel>::paginate(...)->toArray(), $except);

Export mysql data to JSON in a nested and recursivelty way starting from a table?

I have seen several examples to export MySQL tables to JSON, however such examples export data in an aggregated way. For example, take a database where you have two tables "Invoice head" and "Invoice details". "Invoice details" is a child of "Invoice head".The data in JSON is usually represented like:
{
"invoice_head": [
{
"number": 1,
"cliente": "Carlos",
"date": "2016-12-12"
},
{
"number": 2,
"cliente": "Fernando",
"date": "2017-01-01"
}
],
"invoice_details": [
{
"headnumber": 1,
"lineno": 1,
"product": "Shoes",
"quantity": 2
},
{
"headnumber": 1,
"lineno": 2,
"product": "Socks",
"quantity": 1
},
{
"headnumber": 2,
"lineno": 1,
"product": "Laptop",
"quantity": 1
}
],
}
I need to export data in a nested way:
{
"invice_head": [
{
"number": 1,
"cliente": "Carlos",
"date": "2016-12-12",
"invice_details": [
{
"headnumber": 1,
"lineno": 1,
"product": "Shoes",
"quantity": 2
},
{
"headnumber": 1,
"lineno": 2,
"product": "Socks",
"quantity": 1
}
]
},
{
"number": 2,
"cliente": "Fernando",
"date": "2017-01-01"
"invice_details": [
{
"headnumber": 2,
"lineno": 1,
"product": "Laptop",
"quantity": 1
}
]
}
]
}
For this I guess one needs to start in a table and recursively go through its childs for each record.
Does anybody knows if there is anything that does it? I don't want to reinvent the wheel.

Getting error while parsing json response from a dynamic {System.RuntimeType} variable

I'm working on some code in which uses dynamic variables jsonResponse .
dynamic jsonResponse = JsonConvert.DeserializeObject(response);
This variable contains collection of hotel list in json format. From this collection I am getting roomlist collection in a new variable roomResponseList :
var roomResponseList = jsonResponse["hotels"]["hotels"][rooms].roomResponseList;
I am getting first room detail into **JObject responseRateKeys **:
foreach (var roomByResponse in roomResponseList)
{
JObject responseRateKeys = JObject.Parse(roomByResponse.ToString());
var boardNameListByResponse = responseRateKeys.AsJEnumerable().AsEnumerable()
.Select(t => t["rates"]["boardName"].ToString().Trim())
.Distinct()
.ToList();
}
But when I am trying to get any item list from JObject by using linq lambda, I am getting error,
"Cannot access child value on Newtonsoft.Json.Linq.JProperty."
Value of roomByResponse=
{ "code": "DBL.KG-NM", "name": "DOUBLE KING BED NON SMOKING", "rates": [ { "rateKey": "20171217|20171219|W|256|237403|DBL.KG-NM|ID_B2B_26|RO|IWH25|1~1~0||N#AFF5C93E36054661ADCBC14A78A532AE1007", "rateClass": "NRF", "rateType": "RECHECK", "net": "186.04", "allotment": 99, "paymentType": "AT_WEB", "packaging": false, "boardCode": "RO", "boardName": "ROOM ONLY", "cancellationPolicies": [ { "amount": "149.63", "from": "2017-07-14T03:29:00+05:30" } ], "rooms": 1, "adults": 1, "children": 0, "dailyRates": [ { "offset": 1, "dailyNet": "93.02" }, { "offset": 2, "dailyNet": "93.02" } ] }, { "rateKey": "20171217|20171219|W|256|237403|DBL.KG-NM|ID_B2B_26|BB|IWB25|1~1~0||N#AFF5C93E36054661ADCBC14A78A532AE1007", "rateClass": "NOR", "rateType": "RECHECK", "net": "238.92", "allotment": 99, "paymentType": "AT_WEB", "packaging": false, "boardCode": "BB", "boardName": "BED AND BREAKFAST", "rooms": 1, "adults": 1, "children": 0, "dailyRates": [ { "offset": 1, "dailyNet": "119.46" }, { "offset": 2, "dailyNet": "119.46" } ] }, { "rateKey": "20171217|20171219|W|256|237403|DBL.KG-NM|ID_B2B_26|RO|IWH25|2~2~1|2|N#AFF5C93E36054661ADCBC14A78A532AE1007", "rateClass": "NRF", "rateType": "RECHECK", "net": "372.06", "allotment": 99, "paymentType": "AT_WEB", "packaging": false, "boardCode": "RO", "boardName": "ROOM ONLY", "cancellationPolicies": [ { "amount": "299.25", "from": "2017-07-14T03:29:00+05:30" } ], "rooms": 2, "adults": 2, "children": 1, "childrenAges": "2", "dailyRates": [ { "offset": 1, "dailyNet": "186.03" }, { "offset": 2, "dailyNet": "186.03" } ] }, { "rateKey": "20171217|20171219|W|256|237403|DBL.KG-NM|ID_B2B_26|BB|IWB25|2~2~1|2|N#AFF5C93E36054661ADCBC14A78A532AE1007", "rateClass": "NOR", "rateType": "RECHECK", "net": "477.84", "allotment": 99, "paymentType": "AT_WEB", "packaging": false, "boardCode": "BB", "boardName": "BED AND BREAKFAST", "rooms": 2, "adults": 2, "children": 1, "childrenAges": "2", "dailyRates": [ { "offset": 1, "dailyNet": "238.92" }, { "offset": 2, "dailyNet": "238.92" } ] } ] }
Thank you
Pravesh Singh
change linq to
responseRateKeys["rates"].AsJEnumerable().Select(t=>t["boardName"]).Distinct().ToList()