Reputation: 576
I have a collection of my relationship. 1 Mailgroup has many ExternalClients.
When I dd this collection like this:
dd($mailgroup->externalClients);
I get this result:
Collection {#304 ▼
#items: array:1 [▼
0 => ExternalClient {#303 ▼
#table: "external_clients"
+timestamps: false
#casts: array:1 [▶]
#fillable: array:7 [▶]
#connection: null
#primaryKey: "id"
#perPage: 15
+incrementing: true
#attributes: array:8 [▼
"id" => 1
"firstname" => "Ganesan "
"lastname" => "Pandaram"
"email" => "[email protected]"
"active" => 1
"lang" => "nl"
"company" => "ypto"
"site_id" => 4
]
#original: array:10 [▶]
#relations: array:1 [▶]
#hidden: []
#visible: []
#appends: []
#guarded: array:1 [▶]
#dates: []
#touches: []
#observables: []
#with: []
#morphClass: null
+exists: true
}
]
}
Now I want I try the $collection->contains() function like this I get nothing.
if ($mailgroup->externalClients->contains('[email protected]')) {
echo 'yes';
}
I am expecting to see 'yes' because we can see that the "[email protected]" is in the collection.
I've also tried this:
if ($mailgroup->externalClients->contains('email', '[email protected]')) {
echo 'yes';
}
This gives me this error:
Object of class Closure could not be converted to int
Upvotes: 0
Views: 1380
Reputation: 5963
Which version of Laravel are you using?
In v5.8 I am able to filter the objects based on attribute name and value.
See:
>>> $users = factory(App\User::class, 3)->make();
=> Illuminate\Database\Eloquent\Collection {#3278
all: [
App\User {#3276
customer_id: 57,
name: "Jeanie Cassin V",
email: "[email protected]",
is_active: true,
email_verified_at: DateTime @184931115 {#3273
date: 1975-11-11 09:45:15.0 UTC (+00:00),
},
last_login_at: "2018-12-16 09:06:01",
},
App\User {#3285
customer_id: 58,
name: "Prof. Lula Moore",
email: "[email protected]",
is_active: true,
email_verified_at: DateTime @270031087 {#3275
date: 1978-07-23 08:38:07.0 UTC (+00:00),
},
last_login_at: "2007-02-19 00:27:52",
},
App\User {#3287
customer_id: 59,
name: "Conrad Hansen",
email: "[email protected]",
is_active: true,
email_verified_at: DateTime @1026743001 {#3289
date: 2002-07-15 14:23:21.0 UTC (+00:00),
},
last_login_at: "1987-10-06 18:45:35",
},
], }
>>> $rs = $users->contains('email', '[email protected]');
=> true
>>> $rs = $users->contains('email', '[email protected]');
=> false
>>> $rs = $users->contains(function($user) { return $user->email === '[email protected]'; });
=> true
>>> $rs = $users->contains(function($user) { return $user->email === '[email protected]'; });
=> false
But as stated this is tested in Laravel 5.8.
You could try using an anonymous function to get a true/false return value with a custom comparison.
It will pass 2 params (in 5.8):
In your case you could skip the second param.
For example:
$email = '[email protected]';
$clientExists = $mailgroup->externalClients->contains(
function (ExternalClient $externalClient) use ($email) {
return $externalClient->email === $email;
});
if ($clientExists) {
// yes
}
If you need the key of the item (object) within the collection you can use:
$result = $collection->contains(
function ($object, $key) {
// check something with $object->x or $key and return bool
});
Upvotes: 0
Reputation: 9693
In tinker I did some test, it seems where
is not the correct way to do this.
>>> App\User::find(1)->roles->where('role_id', '<', 1)
=> Illuminate\Database\Eloquent\Collection {#3185
all: [
App\models\Role {#3176
id: 1,
name: "super-admin",
display_name: "Super Admin",
description: "This will be one permission, that can not be assigned or
modified.",
created_at: "2018-12-13 12:09:07",
updated_at: "2018-12-13 12:09:07",
pivot: Illuminate\Database\Eloquent\Relations\Pivot {#3177
user_id: 1,
role_id: 1,
},
},
],
}
>>>
Dell@DESKTOP-KU6707L MINGW64 /d/work/www/charmboard (master)
$ php artisan tinker
Psy Shell v0.9.9 (PHP 7.2.10 — cli) by Justin Hileman
>>> App\User::find(1)->roles->where('role_id', 1)
=> Illuminate\Database\Eloquent\Collection {#3129
all: [],
}
>>> App\User::find(1)->roles->where('role_id', 1)->count()
=> 0
>>>
and working for
>>> App\models\Role::where('id', 1)->count()
=> 1
and your case is first 1, I think, you can eager load and use where like
>>> App\User::find(1)->roles()->where('role_id', 1)->get()
=> Illuminate\Database\Eloquent\Collection {#3138
all: [
App\models\Role {#3129
id: 1,
name: "super-admin",
display_name: "Super Admin",
description: "This will be one permission, that can not be assigned or
modified.",
created_at: "2018-12-13 12:09:07",
updated_at: "2018-12-13 12:09:07",
pivot: Illuminate\Database\Eloquent\Relations\Pivot {#3128
user_id: 1,
role_id: 1,
},
},
],
}
>>>
Before some days, here, I learned this lesson.
Upvotes: 0
Reputation: 5582
You can try where()
collection helper function. Which will provide the correct result. Below is the result for that:-
$externalClients = $mailgroup->externalClients;
if($externalClients->where('email', '[email protected]')->count() > 0) {
echo "yes";
}
Here is the reference of collection helper function: where() docs.
For Laravel 5.0, you can refer this.
Try this and check. I think this will work.
Upvotes: 1