Remove unmatched criteria records from Eloquent collection - php

I have some problems with Eloquent Eager Loading. I have added whereHas to remove the blog don't meet the comment criteria but the comment stills return empty array. My intention is to completely remove it from the json record.
How can I completely remove the json data chain that does not meet my condition?
My current code:
User::select("id", "name", "email")
->with(['blog', 'blog.author', 'blog.comments' => function ($query) {
$query->where('comment', 'John is here');
}, 'blog.comments.owner'])
->whereHas('blog.comments', function ($query) {
$query->where('comment', 'John is Here');
})
->get();
My current json output is:
{
"id": 1,
"name": "John Smith",
"email": "john.smith#hotmail.com",
"blog": [
{
"id": 1,
"created_at": "2021-04-09T18:08:06.000000Z",
"updated_at": "2021-04-09T10:33:03.000000Z",
"title": "First Blog",
"description": "Awesome",
"users_id": 1,
"cover": null,
"author": {
"id": 1,
"name": "John Smith",
"email": "john.smith#hotmail.com",
"email_verified_at": null,
"created_at": "2021-04-08T13:29:13.000000Z",
"updated_at": "2021-04-08T13:29:13.000000Z",
"role": 0
},
"comments": [
{
"id": 1,
"comment": "John is here",
"blog_id": 1,
"user_id": 1,
"created_at": null,
"updated_at": null,
"owner": {
"id": 1,
"name": "John Smith",
"email": "john.smith#hotmail.com",
"email_verified_at": null,
"created_at": "2021-04-08T13:29:13.000000Z",
"updated_at": "2021-04-08T13:29:13.000000Z",
"role": 0
}
}
]
},
{
"id": 6,
"created_at": "2021-04-12T07:41:43.000000Z",
"updated_at": "2021-04-12T08:01:18.000000Z",
"title": "Second Blog",
"description": "Awesome",
"users_id": 1,
"cover": "images/json_1618213303.png",
"author": {
"id": 1,
"name": "John Smith",
"email": "john.smith#hotmail.com",
"email_verified_at": null,
"created_at": "2021-04-08T13:29:13.000000Z",
"updated_at": "2021-04-08T13:29:13.000000Z",
"role": 0
},
"comments": []
}
]
}
My expected output would be:
{
"id": 1,
"name": "John Smith",
"email": "john.smith#hotmail.com",
"blog": [
{
"id": 1,
"created_at": "2021-04-09T18:08:06.000000Z",
"updated_at": "2021-04-09T10:33:03.000000Z",
"title": "First Blog",
"description": "Awesome",
"users_id": 1,
"cover": null,
"author": {
"id": 1,
"name": "John Smith",
"email": "john.smith#hotmail.com",
"email_verified_at": null,
"created_at": "2021-04-08T13:29:13.000000Z",
"updated_at": "2021-04-08T13:29:13.000000Z",
"role": 0
},
"comments": [
{
"id": 1,
"comment": "John is here",
"blog_id": 1,
"user_id": 1,
"created_at": null,
"updated_at": null,
"owner": {
"id": 1,
"name": "John Smith",
"email": "john.smith#hotmail.com",
"email_verified_at": null,
"created_at": "2021-04-08T13:29:13.000000Z",
"updated_at": "2021-04-08T13:29:13.000000Z",
"role": 0
}
}
]
}
]
}

Try this,
User::select("id", "name", "email")
->with([
'blog' => function ($query) {
$query->whereHas('comments', function ($query) {
$query->where('comment', 'John is Here');
});
},
'blog.comments' => function ($query) {
$query->where('comment', 'John is here');
},
'blog.author',
'blog.comments.owner'])
->get();
You should be applying the constraint on blog eager loading as well. Your query only filters comments of a blog

Related

Laravel Eloquent perform Aggregation function in the pivot relationship

I would like to perform the average rating of respective product which stored in the pivot table called "reviews".Below are my existing code.
Product Model:
public function reviews(){
return $this->belongsToMany(User::class,'reviews')->withPivot('comment','rating')->withTimestamps();
}
public function getProductRatingAttribute(){
return $this->reviews()->average('rating');
}
User Model:
public function reviews(){
return $this->belongsToMany(Product::class,'reviews')->withPivot('comment','rating')->withTimestamps();
}
Migration for the reviews
Schema::create('reviews', function (Blueprint $table) {
$table->id();
$table->timestamps();
$table->unsignedBigInteger('user_id');
$table->unsignedBigInteger('product_id');
$table->string('comment')->nullable();
$table->integer('rating');
$table->foreign('user_id')->references('id')->on('users');
$table->foreign('product_id')->references('id')->on('products');
});
I have attempted to use the below to code construct the expected output but it leads N+1 issue because it does not take advantage of the eager loading of the Laravel Eloquent.
$s = Product::with('reviews')->append('product_rating');
As I check telescope, it produces 6 query which can lead performance issue when the data is large.
Expected output:
{
"msg": [
{
"id": 4,
"created_at": "2021-04-09T07:32:35.000000Z",
"updated_at": "2021-04-09T07:32:35.000000Z",
"name": "MacDonald",
"nickname": "MCD",
"users_id": 1,
"price": "0.00",
"product_rating": "3.3333",
"reviews": [
{
"id": 1,
"name": "John Smith",
"email": "john.smith#hotmail.com",
"email_verified_at": null,
"created_at": "2021-04-08T13:29:13.000000Z",
"updated_at": "2021-04-08T13:29:13.000000Z",
"role": 0,
"pivot": {
"product_id": 4,
"user_id": 1,
"comment": "Ouch",
"rating": 3,
"created_at": "2021-05-01T11:51:26.000000Z",
"updated_at": "2021-05-01T11:52:07.000000Z"
}
},
{
"id": 2,
"name": "Kelvin Ooi",
"email": "kelvin.ooi#hotmail.com",
"email_verified_at": null,
"created_at": "2021-04-08T13:29:13.000000Z",
"updated_at": "2021-04-13T12:07:11.000000Z",
"role": 1,
"pivot": {
"product_id": 4,
"user_id": 2,
"comment": "Ouch",
"rating": 5,
"created_at": "2021-05-01T11:51:26.000000Z",
"updated_at": "2021-05-01T11:52:07.000000Z"
}
},
{
"id": 1,
"name": "John Smith",
"email": "john.smith#hotmail.com",
"email_verified_at": null,
"created_at": "2021-04-08T13:29:13.000000Z",
"updated_at": "2021-04-08T13:29:13.000000Z",
"role": 0,
"pivot": {
"product_id": 4,
"user_id": 1,
"comment": "Ouch",
"rating": 2,
"created_at": "2021-05-01T11:51:26.000000Z",
"updated_at": "2021-05-01T11:52:07.000000Z"
}
}
]
},
{
"id": 10,
"created_at": null,
"updated_at": null,
"name": "Mary Bown",
"nickname": "MB",
"users_id": 1,
"price": "2.88",
"product_rating": "2.0000",
"reviews": [
{
"id": 1,
"name": "John Smith",
"email": "john.smith#hotmail.com",
"email_verified_at": null,
"created_at": "2021-04-08T13:29:13.000000Z",
"updated_at": "2021-04-08T13:29:13.000000Z",
"role": 0,
"pivot": {
"product_id": 10,
"user_id": 1,
"comment": "Ouch",
"rating": 2,
"created_at": "2021-05-01T11:51:26.000000Z",
"updated_at": "2021-05-01T11:52:07.000000Z"
}
}
]
},
{
"id": 11,
"created_at": null,
"updated_at": null,
"name": "Pizza Hut",
"nickname": "pizzahut",
"users_id": 1,
"price": "4.10",
"product_rating": null,
"reviews": [
]
},
{
"id": 12,
"created_at": "2021-04-09T08:00:42.000000Z",
"updated_at": "2021-04-09T08:00:42.000000Z",
"name": "Domino Pizza",
"nickname": "domino",
"users_id": 3,
"price": "0.00",
"product_rating": null,
"reviews": [
]
},
{
"id": 13,
"created_at": "2021-04-26T16:12:53.000000Z",
"updated_at": "2021-04-26T16:12:53.000000Z",
"name": "Chicken Chop",
"nickname": "chickchop",
"users_id": 3,
"price": "0.00",
"product_rating": null,
"reviews": [
]
}
]
}
Appending is performing the query on each record.
Why not perform average on the collection itself?
$s = Product::with('reviews')->get();
$avg = $s->avg('pivot.rating');
Alternatively you can modify the relationship method to include a raw select of the average rating.

Laravel I can't retrieve requester data using with

I am using this package
https://github.com/renoki-co/befriended
My issue is trying to get all my friends posts with my post including user's data, but the problem is the requester data is null.
$user = $request->user();
$followersPost = UserPost::with(['user' => function ($query) use ($user) {
$query->filterFollowingsOf($user);
}])->latest()->get();
return $followersPost;
Response
[
{
"id": 35,
"post_body": "The Requster Post",
"location_id": "4b0da1acf964a520b94c23e3",
"location_title": "Apple Infinite Loop",
"location_icon": "https://ss3.4sqi.net/img/categories_v2/shops/technology_bg_44.png",
"location_coordinate": "{"latitude":37.33167558501772,"longitude":-122.030189037323,"latitudeDelta":0.001,"longitudeDelta":0.001}",
"location_vicinity": "Cupertino - 1 Infinite Loop",
"user_id": 1,
"viewer_ids": null,
"created_at": "2020-12-06T18:08:58.000000Z",
"updated_at": "2020-12-06T18:08:58.000000Z",
"images": [
],
"musics": [
],
"movies": [
],
"emojs": [
],
"user": null
},
{
"id": 34,
"post_body": "Test Post",
"location_id": "4b0da1acf964a520b94c23e3",
"location_title": "Apple Infinite Loop",
"location_icon": "https://ss3.4sqi.net/img/categories_v2/shops/technology_bg_44.png",
"location_coordinate": "{"latitude":37.33167558501772,"longitude":-122.030189037323,"latitudeDelta":0.001,"longitudeDelta":0.001}",
"location_vicinity": "Cupertino - 1 Infinite Loop",
"user_id": 2,
"viewer_ids": null,
"created_at": "2020-12-06T18:08:14.000000Z",
"updated_at": "2020-12-06T18:08:14.000000Z",
"images": [
],
"musics": [
],
"movies": [
],
"emojs": [
],
"user": {
"id": 2,
"_id": "dfa19aa6-510b-4aaf-8475-4386da9de3d0",
"name": "Saleh",
"username": "saleh",
"email": "saleh#gmail.com",
"email_verified_at": null,
"avatar": "http://backend.mf.sa/storage/avatars/1607128041.jpg",
"location": null,
"gender": "male",
"bio": null,
"birthday": null,
"phone": null,
"created_at": "2020-12-05T00:27:02.000000Z",
"updated_at": "2020-12-05T00:27:21.000000Z"
}
},
{
"id": 24,
"post_body": null,
"location_id": null,
"location_title": null,
"location_icon": null,
"location_coordinate": null,
"location_vicinity": null,
"user_id": 3,
"viewer_ids": null,
"created_at": "2020-12-06T01:53:18.000000Z",
"updated_at": "2020-12-06T01:53:18.000000Z",
"images": [
],
"musics": [
{
"id": 4,
"post_id": 24,
"song_name": "Confetti",
"song_preview": "https://cdns-preview-6.dzcdn.net/stream/c-6eb643a05083c023f874f13739fc7c87-3.mp3",
"song_picture": "https://api.deezer.com/album/183603832/image",
"song_artist": "Little Mix",
"created_at": "2020-12-06T01:53:18.000000Z",
"updated_at": "2020-12-06T01:53:18.000000Z"
}
],
"movies": [
],
"emojs": [
{
"id": 16,
"post_id": 24,
"user_id": 3,
"emojy": "015-smile-1",
"created_at": "2020-12-06T01:59:15.000000Z",
"updated_at": "2020-12-06T01:59:15.000000Z",
"user": {
"id": 3,
"_id": "af65864b-f18a-4609-91db-336acbce1486",
"name": "Ali",
"username": "ali2323",
"email": "ali#gmail.com",
"email_verified_at": null,
"avatar": null,
"location": null,
"gender": "male",
"bio": null,
"birthday": null,
"phone": null,
"created_at": "2020-12-05T04:05:50.000000Z",
"updated_at": "2020-12-05T04:05:50.000000Z"
}
},
{
"id": 17,
"post_id": 24,
"user_id": 1,
"emojy": "089-broken-heart",
"created_at": "2020-12-06T16:58:07.000000Z",
"updated_at": "2020-12-06T16:58:24.000000Z",
"user": {
"id": 1,
"_id": "737ba284-424d-4b0d-8a56-2e845603f2ba",
"name": "Mohammed",
"username": "mohammed",
"email": "h4ck3r.x0#gmail.com",
"email_verified_at": null,
"avatar": "http://backend.mf.sa/storage/avatars/1607128001.jpg",
"location": null,
"gender": "male",
"bio": null,
"birthday": null,
"phone": null,
"created_at": "2020-12-05T00:26:09.000000Z",
"updated_at": "2020-12-05T00:26:41.000000Z"
}
},
{
"id": 19,
"post_id": 24,
"user_id": 2,
"emojy": "021-sad",
"created_at": "2020-12-06T16:58:36.000000Z",
"updated_at": "2020-12-06T16:58:36.000000Z",
"user": {
"id": 2,
"_id": "dfa19aa6-510b-4aaf-8475-4386da9de3d0",
"name": "Saleh",
"username": "saleh",
"email": "saleh#gmail.com",
"email_verified_at": null,
"avatar": "http://backend.mf.sa/storage/avatars/1607128041.jpg",
"location": null,
"gender": "male",
"bio": null,
"birthday": null,
"phone": null,
"created_at": "2020-12-05T00:27:02.000000Z",
"updated_at": "2020-12-05T00:27:21.000000Z"
}
}
],
"user": {
"id": 3,
"_id": "af65864b-f18a-4609-91db-336acbce1486",
"name": "Ali",
"username": "ali2323",
"email": "ali#gmail.com",
"email_verified_at": null,
"avatar": null,
"location": null,
"gender": "male",
"bio": null,
"birthday": null,
"phone": null,
"created_at": "2020-12-05T04:05:50.000000Z",
"updated_at": "2020-12-05T04:05:50.000000Z"
}
}
]
As you can see the first object in the array dosen't include the user data.
So what should i do $query->filterFollowingsOf($user); to include my data?
I think the with callback is used for modifying the query that selects the user data. Instead, try using a whereHas method that filters the related users.
$user = $request->user();
$followersPost = UserPost
::with('user')
->whereHas('user', function ($query) use ($user) {
$query->filterFollowingsOf($user);
})
->latest()
->get();
return $followersPost;
I'd also recommend using paginate() instead of get() for performance when there could be a significant number of posts.
Edit:
To get either your friend's posts or your posts, try:
$followersPost = UserPost
::with('user')
->whereHas('user', function ($query) use ($user) {
$query->filterFollowingsOf($user);
})
->orWhere('user_id', $user->id)
->latest()
->get();

filter collection to remove items that have an empty array

I have a collection that looks like this,
[
{
"id": 1,
"title": "Cooking",
"deleted_at": null,
"created_at": null,
"updated_at": null,
"listings": [
{
"id": 6,
"title": "Listing Number 1",
"slug": "listing-number-1",
"description": "Description",
"booking_details": "Booking Details",
"cost": "25.00",
"active": 0,
"user_id": 2,
"deleted_at": null,
"created_at": "2020-06-03T22:35:56.000000Z",
"updated_at": "2020-06-03T22:35:56.000000Z",
"pivot": {
"category_id": 1,
"listing_id": 6
},
"assets": [],
"primary_image": []
},
{
"id": 7,
"title": "Listing Number 1",
"slug": "listing-number-1",
"description": "Description",
"booking_details": "Booking Details",
"cost": "25.00",
"active": 0,
"user_id": 2,
"deleted_at": null,
"created_at": "2020-06-03T22:36:10.000000Z",
"updated_at": "2020-06-03T22:36:10.000000Z",
"pivot": {
"category_id": 1,
"listing_id": 7
},
"assets": [],
"primary_image": []
},
{
"id": 8,
"title": "Listing Number 1",
"slug": "listing-number-1",
"description": "Description",
"booking_details": "Booking Details",
"cost": "25.00",
"active": 0,
"user_id": 2,
"deleted_at": null,
"created_at": "2020-06-03T22:36:26.000000Z",
"updated_at": "2020-06-03T22:36:26.000000Z",
"pivot": {
"category_id": 1,
"listing_id": 8
},
"assets": [],
"primary_image": []
},
{
"id": 9,
"title": "Listing Number 1",
"slug": "listing-number-1",
"description": "Description",
"booking_details": "Booking Details",
"cost": "25.00",
"active": 0,
"user_id": 2,
"deleted_at": null,
"created_at": "2020-06-03T22:36:42.000000Z",
"updated_at": "2020-06-03T22:36:42.000000Z",
"pivot": {
"category_id": 1,
"listing_id": 9
},
"assets": [],
"primary_image": []
},
{
"id": 10,
"title": "Listing Number 1",
"slug": "listing-number-1",
"description": "Description",
"booking_details": "Booking Details",
"cost": "25.00",
"active": 0,
"user_id": 2,
"deleted_at": null,
"created_at": "2020-06-03T22:37:40.000000Z",
"updated_at": "2020-06-03T22:37:40.000000Z",
"pivot": {
"category_id": 1,
"listing_id": 10
},
"assets": [],
"primary_image": []
},
{
"id": 11,
"title": "Listing Number 2",
"slug": "listing-number-2",
"description": "Description 1",
"booking_details": "Booking Details 1",
"cost": "25.00",
"active": 0,
"user_id": 2,
"deleted_at": null,
"created_at": "2020-06-03T22:46:31.000000Z",
"updated_at": "2020-06-03T22:46:31.000000Z",
"pivot": {
"category_id": 1,
"listing_id": 11
},
"assets": [
{
"id": 3,
"type": "image",
"path": "https://xx-xxxx-xxxx-1.s3.eu-west-2.amazonaws.com/listing-number-2/primary-image-lg.jpg",
"is_primary": 1,
"assetable_type": "App\\Listing",
"assetable_id": 11,
"user_id": 2,
"deleted_at": null,
"created_at": "2020-06-03T22:46:33.000000Z",
"updated_at": "2020-06-03T22:46:33.000000Z"
},
{
"id": 4,
"type": "image",
"path": "https://xx-xxxx-xxxx-1.s3.eu-west-2.amazonaws.com/listing-number-2/primary-image-sm.jpg",
"is_primary": 1,
"assetable_type": "App\\Listing",
"assetable_id": 11,
"user_id": 2,
"deleted_at": null,
"created_at": "2020-06-03T22:46:33.000000Z",
"updated_at": "2020-06-03T22:46:33.000000Z"
}
],
"primary_image": [
{
"id": 3,
"type": "image",
"path": "https://xx-xxxx-xxxx-1.s3.eu-west-2.amazonaws.com/listing-number-2/primary-image-lg.jpg",
"is_primary": 1,
"assetable_type": "App\\Listing",
"assetable_id": 11,
"user_id": 2,
"deleted_at": null,
"created_at": "2020-06-03T22:46:33.000000Z",
"updated_at": "2020-06-03T22:46:33.000000Z"
},
{
"id": 4,
"type": "image",
"path": "https://xx-xxxx-xxxx-1.s3.eu-west-2.amazonaws.com/listing-number-2/primary-image-sm.jpg",
"is_primary": 1,
"assetable_type": "App\\Listing",
"assetable_id": 11,
"user_id": 2,
"deleted_at": null,
"created_at": "2020-06-03T22:46:33.000000Z",
"updated_at": "2020-06-03T22:46:33.000000Z"
}
]
},
{
"id": 12,
"title": "Listing Number 3",
"slug": "listing-number-3",
"description": "Description 1",
"booking_details": "Booking Details 1",
"cost": "25.00",
"active": 0,
"user_id": 2,
"deleted_at": null,
"created_at": "2020-06-03T22:50:31.000000Z",
"updated_at": "2020-06-03T22:50:31.000000Z",
"pivot": {
"category_id": 1,
"listing_id": 12
},
"assets": [],
"primary_image": []
},
{
"id": 13,
"title": "Listing Number 3",
"slug": "listing-number-3",
"description": "Description 1",
"booking_details": "Booking Details 1",
"cost": "25.00",
"active": 0,
"user_id": 2,
"deleted_at": null,
"created_at": "2020-06-03T22:57:12.000000Z",
"updated_at": "2020-06-03T22:57:12.000000Z",
"pivot": {
"category_id": 1,
"listing_id": 13
},
"assets": [],
"primary_image": []
},
{
"id": 15,
"title": "Listing Number 3",
"slug": "listing-number-3",
"description": "Description 1",
"booking_details": "Booking Details 1",
"cost": "25.00",
"active": 0,
"user_id": 2,
"deleted_at": null,
"created_at": "2020-06-03T23:00:49.000000Z",
"updated_at": "2020-06-03T23:00:49.000000Z",
"pivot": {
"category_id": 1,
"listing_id": 15
},
"assets": [],
"primary_image": []
},
{
"id": 16,
"title": "Listing Number 3",
"slug": "listing-number-3",
"description": "Description 1",
"booking_details": "Booking Details 1",
"cost": "25.00",
"active": 0,
"user_id": 2,
"deleted_at": null,
"created_at": "2020-06-03T23:01:21.000000Z",
"updated_at": "2020-06-03T23:01:21.000000Z",
"pivot": {
"category_id": 1,
"listing_id": 16
},
"assets": [],
"primary_image": []
},
{
"id": 17,
"title": "Listing Number 3",
"slug": "listing-number-3",
"description": "Description 1",
"booking_details": "Booking Details 1",
"cost": "25.00",
"active": 0,
"user_id": 2,
"deleted_at": null,
"created_at": "2020-06-03T23:01:26.000000Z",
"updated_at": "2020-06-03T23:01:26.000000Z",
"pivot": {
"category_id": 1,
"listing_id": 17
},
"assets": [],
"primary_image": []
},
{
"id": 18,
"title": "Listing Number 3",
"slug": "listing-number-3",
"description": "Description 1",
"booking_details": "Booking Details 1",
"cost": "25.00",
"active": 0,
"user_id": 2,
"deleted_at": null,
"created_at": "2020-06-03T23:01:49.000000Z",
"updated_at": "2020-06-03T23:01:49.000000Z",
"pivot": {
"category_id": 1,
"listing_id": 18
},
"assets": [],
"primary_image": []
},
{
"id": 19,
"title": "Listing Number 3",
"slug": "listing-number-3",
"description": "Description 1",
"booking_details": "Booking Details 1",
"cost": "25.00",
"active": 0,
"user_id": 2,
"deleted_at": null,
"created_at": "2020-06-03T23:02:19.000000Z",
"updated_at": "2020-06-03T23:02:19.000000Z",
"pivot": {
"category_id": 1,
"listing_id": 19
},
"assets": [],
"primary_image": []
},
{
"id": 20,
"title": "Listing Number 3",
"slug": "listing-number-3",
"description": "Description 1",
"booking_details": "Booking Details 1",
"cost": "25.00",
"active": 0,
"user_id": 2,
"deleted_at": null,
"created_at": "2020-06-03T23:03:31.000000Z",
"updated_at": "2020-06-03T23:03:31.000000Z",
"pivot": {
"category_id": 1,
"listing_id": 20
},
"assets": [],
"primary_image": []
},
{
"id": 21,
"title": "Listing Number 3",
"slug": "listing-number-3",
"description": "Description 1",
"booking_details": "Booking Details 1",
"cost": "25.00",
"active": 0,
"user_id": 2,
"deleted_at": null,
"created_at": "2020-06-03T23:06:25.000000Z",
"updated_at": "2020-06-03T23:06:25.000000Z",
"pivot": {
"category_id": 1,
"listing_id": 21
},
"assets": [
{
"id": 5,
"type": "image",
"path": "https://xx-xxxx-xxxx-1.s3.eu-west-2.amazonaws.com/listing-number-3/primary-image-lg.jpg",
"is_primary": 1,
"assetable_type": "App\\Listing",
"assetable_id": 21,
"user_id": 2,
"deleted_at": null,
"created_at": "2020-06-03T23:06:26.000000Z",
"updated_at": "2020-06-03T23:06:26.000000Z"
},
{
"id": 6,
"type": "image",
"path": "https://xx-xxxx-xxxx-1.s3.eu-west-2.amazonaws.com/listing-number-3/primary-image-sm.jpg",
"is_primary": 1,
"assetable_type": "App\\Listing",
"assetable_id": 21,
"user_id": 2,
"deleted_at": null,
"created_at": "2020-06-03T23:06:27.000000Z",
"updated_at": "2020-06-03T23:06:27.000000Z"
}
],
"primary_image": [
{
"id": 5,
"type": "image",
"path": "https://xx-xxxx-xxxx-1.s3.eu-west-2.amazonaws.com/listing-number-3/primary-image-lg.jpg",
"is_primary": 1,
"assetable_type": "App\\Listing",
"assetable_id": 21,
"user_id": 2,
"deleted_at": null,
"created_at": "2020-06-03T23:06:26.000000Z",
"updated_at": "2020-06-03T23:06:26.000000Z"
},
{
"id": 6,
"type": "image",
"path": "https://xx-xxxx-xxxx-1.s3.eu-west-2.amazonaws.com/listing-number-3/primary-image-sm.jpg",
"is_primary": 1,
"assetable_type": "App\\Listing",
"assetable_id": 21,
"user_id": 2,
"deleted_at": null,
"created_at": "2020-06-03T23:06:27.000000Z",
"updated_at": "2020-06-03T23:06:27.000000Z"
}
]
}
]
}
]
I only want to see a collection that contains items that don't have empty assets array,
I have tried this,
$category = Category::whereHas('listings.assets')->with(['listings.assets', 'listings.primaryImage' => function($query){
$query->where('assets.is_primary', '=', 1);
}])->get();
return $category->filter(function($item){
foreach($item->listings as $i) {
return !empty($i->assets);
}
});
But this just returns an empty [] what am I doing wrong?
You are returning in your loop, so as soon as it finds listings that does not have assets it will break the loop and be false. Instead use contains(), that check if any of the elements, passes the given condition. If one does, it will return true. Therefor not breaking the loop on empty collections, as you do now.
return $category->filter(function($item){
return $item->listings->contains(function ($listing) {
return $listing->assets->isNotEmpty();
});
});

How can I hidden data in JSON if variable is empty

I got a some trouble in my Laravel application, in Search function, when I do search the result is
{
"data": [
{
"id": 2,
"user_id": 8,
"identity_number": "213918273",
"name": "Pekerja_2",
"gender_id": 1,
"date_of_birth": "1999-05-25",
"address": "Jalan Bandung Raya no 50",
"province_id": 32,
"city_id": 3273,
"district_id": 3273160,
"phone": "4232343432",
"image": null,
"created_at": "2018-01-11 10:59:54",
"updated_at": "2018-01-11 10:59:54",
"partner_id": null,
"skill": [
{
"id": 3,
"worker_id": 2,
"skill_id": 6,
"sub_skill_id": 18,
"created_at": "2018-01-15 13:06:48",
"updated_at": "2018-01-15 13:06:48",
"price": null,
"unit": null
}
]
},
{
"id": 3,
"user_id": 16,
"identity_number": "213918273",
"name": "Pekerja_3",
"gender_id": 1,
"date_of_birth": "1999-05-25",
"address": "Jalan Bandung Raya no 50",
"province_id": 32,
"city_id": 3273,
"district_id": 3273160,
"phone": "2345234234",
"image": null,
"created_at": "2018-01-15 13:06:48",
"updated_at": "2018-01-15 13:06:48",
"partner_id": null,
"skill": []
}
]
}
as you can see that "Skill" with id number 3 is empty, I want all in id number 3 is empty also.
My controller is :
$worker = Worker::with(['skill' => function($q) use ($request) {
$q->where('worker_skills.sub_skill_id', $request['sub_skill_id']);
}])->whereHas('skill');
And I want something like this :
{
"data": [
{
"id": 2,
"user_id": 8,
"identity_number": "213918273",
"name": "Pekerja_2",
"gender_id": 1,
"date_of_birth": "1999-05-25",
"address": "Jalan Bandung Raya no 50",
"province_id": 32,
"city_id": 3273,
"district_id": 3273160,
"phone": "2534234234",
"image": null,
"created_at": "2018-01-11 10:59:54",
"updated_at": "2018-01-11 10:59:54",
"partner_id": null,
"skill": [
{
"id": 3,
"worker_id": 2,
"skill_id": 6,
"sub_skill_id": 18,
"created_at": "2018-01-15 13:06:48",
"updated_at": "2018-01-15 13:06:48",
"price": null,
"unit": null
}
]
},
]
}
The point is, if "skill" variable is empty then data not show and vice versa.
Thankyou any help will appreciate, sorry for bad english
You can add a callback to your whereHas function with the same filter as the with function
$worker = Worker::with(['skill' => function($q) use ($request) {
$q->where('worker_skills.sub_skill_id', $request['sub_skill_id']);
}])
->whereHas('skill', function($q) use ($request) {
$q->where('worker_skills.sub_skill_id', $request['sub_skill_id']);
})
->get();
You can try this $worker = Worker:has('skill')->get();
Only worker that have at least one skill are contained in the collection

Subscribed topics

In my forum I'm showing all topics. It looks like this:
So a user can subscribe by clicking on the red hearth.
I'm loading the topics with this json:
{
"forum": {
"id": 1,
"slug": "test",
"name": "test",
"description": "test",
"created_at": null,
"updated_at": null
},
"topics": {
"total": 6,
"per_page": 5,
"current_page": 1,
"last_page": 2,
"next_page_url": "http://forum.dev/api/forum/test?page=2",
"prev_page_url": null,
"from": 1,
"to": 5,
"data": [
{
"id": 1,
"slug": "1",
"name": "1",
"description": "1",
"forum_id": 1,
"created_at": null,
"updated_at": null
},
{
"id": 2,
"slug": "2",
"name": "1",
"description": "1\t",
"forum_id": 1,
"created_at": null,
"updated_at": null
},
{
"id": 3,
"slug": "1",
"name": "1",
"description": "1\t",
"forum_id": 1,
"created_at": null,
"updated_at": null
},
{
"id": 4,
"slug": "1",
"name": "1",
"description": "1",
"forum_id": 1,
"created_at": null,
"updated_at": null
},
{
"id": 5,
"slug": "1",
"name": "1",
"description": "1",
"forum_id": 1,
"created_at": null,
"updated_at": null
}
]
}
}
I'm returning that ^ like this:
$forum->topics()->orderBy('created_at', 'DESC')->paginate(5);
So how do I get a subscribe value on every topic object?
So like this:
"data": [
{
"id": 1,
"slug": "1",
"name": "1",
"description": "1",
"forum_id": 1,
"created_at": null,
"updated_at": null,
"subscribed": true
},
I already made this on my topic model:
/**
* #return mixed
*/
public function subscriptions()
{
return Topic::subscribedBy(Auth::user())->get();
}
And it's working. But how do I send that ^ with every topic.
You can add an attribute (which is not present in the database) by creating an accessor.
public function getSubscriptionsAttribute()
{
return Topic::subscribedBy(Auth::user())->get();
}
and then adding it to the $append property.
protected $appends = ['subscriptions'];
If you're using the $visible whitelist you might have to add it to that property too.
Source (Its all the way in the bottom.)

Categories