Laravel Eloquent Collection filter by pivot id - sql

This is my Apartment integrated with services
"id": 26,
"user_id": 1,
"title": "SAN MARINO",
"slug": "san-marino",
"rooms": 1,
"bathrooms": 1,
"beds": 1,
"squared_meters": 12,
"address": "San Marino, Carpi",
"latitude": "44.80924",
"longitude": "10.91565",
"image": "apartment_image/BMRQZSXLdWviqDwmHgqLzrmzG1hJzJGOq7DujnRB.jpg",
"is_visible": 1,
"floor": 1,
"price": 120,
"description": "2",
"created_at": "2022-02-21T21:41:53.000000Z",
"updated_at": "2022-02-21T21:41:53.000000Z",
"services": [
{
"id": 2,
"name": "Posto Macchina",
"slug": "posto-macchina",
"created_at": "2022-02-21T08:59:53.000000Z",
"updated_at": "2022-02-21T08:59:53.000000Z",
"pivot": {
"apartment_id": 26,
"service_id": 2
}
}
]
}
I use to filter my collection( $apartment_list = ApartmentResource::collection(Apartment::with(['services'])->get());)
using multiple WHERE, like this: $apartment_list = $apartment_list->where('rooms', '>=', $rooms);
How can i filter my Apartment refering to the pivot column service_id or services[id]?

There is filter method for the collection. You may create a callback for a single apartament and filter in any way you want:
$apartment_list->filter(function ($apartament) {
// ...
});

you can use try with this:
$serviceId = value_of_service_id;
$apartment_list = ApartmentResource::collection(Apartment:: whereHas('services', function ($q) use ($serviceId) {
$q->where('service_id', $serviceId);
})->get());

Related

Find authors with age under 40 in my postgresql table

I have the following table with one row. I have tried to query this table to return authors under the age of 40 and have been unable to do so.
CREATE TABLE bookstuff (
data JSON
);
insert into bookstuff(data)
VALUES('
{
"the_books": {
"publishers": [
{
"name": "Dunder Mifflin",
"address": "Scranton, PA",
"country": "USA",
"CEO": "David Wallace"
},
{
"name": "Sabre",
"address": "Tallahassee, FL",
"country": "USA",
"CEO": "Jo Bennett"
},
{
"name": "Michael Scott Paper company",
"address": "Scranton, PA",
"country": "USA",
"CEO": "Michael Gary Scott"
},
{
"name": "Vance Refrigeration",
"address": "Scranton, PA",
"country": "USA",
"CEO": "Bob Vance"
}
],
"authors": [
{
"id": 1,
"name": "Michael Scott",
"age": 45,
"country": "USA",
"agentname": "Jan Levinson",
"books_written": "book1"
},
{
"id": 2,
"name": "Jim Halpert",
"age": 35,
"country": "USA",
"agentname": "Pam Beesly",
"books_written": "book3"
},
{
"id": 3,
"name": "Dwight Schrute",
"age": 40,
"country": "USA",
"agentname": "Angela Martin",
"books_written": "book2"
},
{
"id": 4,
"name": "Pam Halpert",
"age": 35,
"country": "USA",
"agentname": "Angela Martin",
"books_written": "book4"
}
],
"books": [
{
"isbn": "book1",
"title": "The Dundies",
"price": 10.99,
"year": 2005,
"publishername": "Dunder Mifflin"
},
{
"isbn": "book2",
"title": "Bears, Beets, Battlestar Galactica",
"price": 8.99,
"year": 2006,
"publishername": "Dunder Mifflin"
},
{
"isbn": "book3",
"title": "The Sabre Store",
"price": 12.99,
"year": 2007,
"publishername": "Sabre"
},
{
"isbn": "book4",
"title": "Branch Wars",
"price": 14.99,
"year": 2015,
"publishername": "Sabre"
}
]
}
}');
I have tried the following query to get the author's age
SELECT data->'the_books'->'authors'
FROM bookstuff
WHERE (data->'the_books'->'authors'->>'age')::integer > 40;
I expect it to return two values 'Jim halpert' and 'pam halpert' but instead I get no result back, not even null.
I have also tried this query, just to see if i could get anything back at all from the table and still no results:
SELECT data->'the_books'->'authors'
FROM bookstuff
where (data->'the_books'->'authors'->'name')::jsonb ? 'Michael Scott';
I'm new to postgresql, is there a different way I should be going about this?
Using json_array_elements:
select (v -> 'name')#>>'{}' from bookstuff b
cross join json_array_elements(b.data -> 'the_books' -> 'authors') v
where ((v -> 'age')#>>'{}')::int < 40
See fiddle
Another option, slightly more verbose:
select distinct(author->>'name') as author_name from
(select json_array_elements(b.data->'the_books'->'authors') author from bookstuff b) author
where (author->>'age')::int < 40
The distinct might be unnecessary if you really just have one database row and no duplicates in the authors array of that row.
Three considerations of why your final solution doesn't work
where filters out rows - this happens before the 'select'. the row contains everything in this case.
'?' predicate matches an array containing your choosen value "Does the key/element string exist within the JSON value?" You don't have a simple array here array->'key' doesn't pick that attribute into a new array
your select projection isn't called however it was it would contain the whole array (remember where doesn't transform just filters out rows)

Can not use jsonpath expression in Postman

I have Json like this, and i tried to print a value i wanted by using JSonpath expression, detail is i wanted to print first_name of user has id = 10
{
"page": 2,
"per_page": 6,
"total": 12,
"total_pages": 2,
"data": [
{
"id": 7,
"email": "michael.lawson#reqres.in",
"first_name": "Michael",
"last_name": "Lawson",
"avatar": "https://reqres.in/img/faces/7-image.jpg"
},
{
"id": 8,
"email": "lindsay.ferguson#reqres.in",
"first_name": "Lindsay",
"last_name": "Ferguson",
"avatar": "https://reqres.in/img/faces/8-image.jpg"
},
{
"id": 9,
"email": "tobias.funke#reqres.in",
"first_name": "Tobias",
"last_name": "Funke",
"avatar": "https://reqres.in/img/faces/9-image.jpg"
},
{
"id": 10,
"email": "byron.fields#reqres.in",
"first_name": "Byron",
"last_name": "Fields",
"avatar": "https://reqres.in/img/faces/10-image.jpg"
},
{
"id": 11,
"email": "george.edwards#reqres.in",
"first_name": "George",
"last_name": "Edwards",
"avatar": "https://reqres.in/img/faces/11-image.jpg"
},
{
"id": 12,
"email": "rachel.howell#reqres.in",
"first_name": "Rachel",
"last_name": "Howell",
"avatar": "https://reqres.in/img/faces/12-image.jpg"
}
],
"support": {
"url": "https://reqres.in/#support-heading",
"text": "To keep ReqRes free, contributions towards server costs are appreciated!"
}
}
I wrote a simple script in tests in postman to do that
var jsonData = pm.response.json();
let x = jsonData.data[?(#.id==8)].first_name)
console.log(x)
But the response in tests is
There was an error in evaluating the test script: SyntaxError: Unexpected token '?'
the result as like this picture
You can use find() to find the object match your condition.
var jsonData = pm.response.json();
let x = jsonData.data.find(item => item.id === 8).first_name;
console.log(x);
//Lindsay

Laravel 8 hasManyThrough Iteration

I have just started my journey with Laravel and PHP.
I have this route:
Route::get('/admin/applications/staff-role', function () {
$staff = StaffRole::with('applications')->where('id', '=', '1')->get();
return $staff;
});
which is the result of hasManyThrough query and returns this result:
[
{
"id": 1,
"staff_role_label": "Staff 1",
"staff_role_description": "Staff Role 1",
"staff_role_abbreviation": "SR1",
"deleted_at": null,
"applications": [
{
"id": 1,
"vacancy_id": 1,
"hours_per_week": "9",
"contract_type": "Full-Time",
"desired_shift_option": "Weekends",
"name": "John",
"surname": "Doe",
"mobile_phone_number": "07911 123456",
"email": "test1#test.com",
"application_status": 1,
"is_staff": 1,
"staff_status": 0,
"deleted_at": null,
"laravel_through_key": 1
},
{
"id": 2,
"vacancy_id": 1,
"hours_per_week": "9",
"contract_type": "Full-Time",
"desired_shift_option": "Weekends",
"name": "Jane",
"surname": "Doe",
"mobile_phone_number": "07911 123456",
"email": "test2#test.com",
"application_status": 1,
"is_staff": 1,
"staff_status": 0,
"deleted_at": null,
"laravel_through_key": 1
}
]
}
]
So far, so good, but how can I count how many applications I have in the array?
Thanks.

Add virtual column for order by it but does not return it

I have an entity which has a point (postgis) property.I need to return a collection of that entity ordered by the distance between coordinates of user and the point of entity.
For this, Im adding an aggregate function for calculate that distance and add it in ORDER BY, but I dont want to return it. I only need that return and array of objects of entity.
Without order by, the result is:
[
{
"user": "/api/users/1",
"id": 1,
"gender": "MALE",
"createdAt": "2019-04-05T11:03:03+02:00",
"updateAt": "2019-04-11T11:34:06+02:00",
"birthdate": "1991-05-13T08:02:32+02:00",
"deletedAt": null,
"town": "Miami"
},
{
"user": "/api/users/3",
"id": 2,
"gender": "MALE",
"createdAt": "2019-04-05T13:59:30+02:00",
"updateAt": "2019-04-11T10:57:40+02:00",
"birthdate": "1999-04-05T11:48:46+02:00",
"deletedAt": null,
"town": "New York"
},
{
"user": "/api/users/7",
"id": 3,
"gender": "MALE",
"createdAt": "2019-04-11T11:11:03+02:00",
"updateAt": "2019-04-11T11:11:03+02:00",
"birthdate": "1991-05-13T08:02:32+02:00",
"deletedAt": null,
"town": "New York"
}
]
When I add the next code for ORDER BY disntace (calculated between coordinates of user and the point)
$queryBuilder
->addSelect("ST_Distance(o.point, ST_Point(:longitude,:latitude)) AS distance")
->addOrderBy("distance", "ASC")
->setParameter("longitude", $longitude)
->setParameter("latitude", $latitude)
;
I get:
[
{
"0": {
"user": "/api/users/1",
"id": 1,
"gender": "MALE",
"createdAt": "2019-04-05T11:03:03+02:00",
"updateAt": "2019-04-11T11:34:06+02:00",
"birthdate": "1991-05-13T08:02:32+02:00",
"deletedAt": null,
"town": "Miami"
},
"distance": "106496.35623204"
},
{
"0": {
"user": "/api/users/7",
"id": 3,
"gender": "MALE",
"createdAt": "2019-04-11T11:11:03+02:00",
"updateAt": "2019-04-11T11:11:03+02:00",
"birthdate": "1991-05-13T08:02:32+02:00",
"deletedAt": null,
"town": "New York"
},
"distance": "109073.2944295"
},
{
"0": {
"user": "/api/users/3",
"id": 2,
"gender": "MALE",
"createdAt": "2019-04-05T13:59:30+02:00",
"updateAt": "2019-04-11T10:57:40+02:00",
"birthdate": "1999-04-05T11:48:46+02:00",
"deletedAt": null,
"town": "New York"
},
"distance": "285892.32591062"
}
]
I need to the result seem like the 1st json. It is possible to add ORDER BY but remove/hide the distance property?
As of doctrine 2.2, Scalar mappings can now be omitted from DQL result,
using the HIDDEN keyword, so to omit the computed field from the result:
->addSelect("ST_Distance(o.point, ST_Point(:longitude,:latitude)) AS HIDDEN distance")
DQL select expressions documentation
DQL examples

Right way to use function field() in yii2

I am writing REST API for my project.
field() function in my Model:
public function fields()
{
$fields = parent::fields();
// remove fields that contain sensitive information
unset($fields['media'], $fields['content']);
return $fields;
}
I have a 2 action:
/api/resources - get all resources lists
This api return:
"items":
[
{
"ID": 1,
"category_id": 1,
"title": "tset",
"image": "1437537044.png",
"ins_date": "2015-07-22 00:00:00",
"count": 20
},
{
"ID": 2,
"category_id": 1,
"title": "tset",
"image": "1437537176.png",
"ins_date": "2015-07-22 00:00:00",
"count": 0
},
/api/resources/view?id=1 - get all information about resource ID=1
{
"ID": 1,
"category_id": 1,
"title": "tset",
"image": "1437537044.png",
"ins_date": "2015-07-22 00:00:00",
"count": 21
}
I get all resources, but I want to get all fields when I call actionView($id) like this:
{
"ID": 1,
"category_id": 1,
"title": "tset", // I want to get response with this
"content": "test", //and this fields
"media": "test",
"image": "1437537044.png",
"ins_date": "2015-07-22 00:00:00",
"count": 22
}
HOw can solve this problem? Help me?
use subclass of models with different fields()
use Yii::$app->controller->action->uniqueId
public function fields()
{
if(Yii::$app->controller->action->uniqueId == 'controller/action'){
return ['field_1','field_2','field_3','field_4'];
}else{
return ['field_1','field_3'];
}
}
Extended yii\rest\Serializer change init() and getRequestedFields()