如何在过滤的查询结果上使用Laravel的attach()?

I would like to use attach() on a filtered Builder result:

$users = User::whereIn('type', array(1, 2))->get();

$usersType_1 = $users->filter(function($item) {
    return $item->type == 1;
});

$usersType_2 = $users->filter(function($item) {
    return $item->type == 2;
});

$usersType_1->role()->attach(3);
$usersType_2->role()->attach(4);

So, I need to attach the role based on the user type. The role() method is specified on the User model

The attach() part from the code above throws the following error: Method role() doesn't exist - which I assume happens because filter() returns a Collection.

Is there a working way to attach pivot entries on filtered Builder result? Or do I need to run 2 separate queries and run attach() on them respectively?

Why not just do:

$usersType_1 = $users->where('type', 1); // or whereType(1)
$usersType_1->role()->attach(3);

$usersType_2 = $users->where('type', 2); // or whereType(1)
$usersType_2->role()->attach(4);

I think the "Method role() doesn't exist" exception occurs because you're filtering an Eloquent Collection.

EDIT: I see why this doesn't work. It's because you're trying to attach an entire collection to a role. It would work if you used find() and then attached a role.

So you should loop over all the users with type 1 and attach the role

foreach ($usersType_1 as $user) {
   $user->role()->attach(3);
}

You couldn't use role method no collection instead of User model. Try by:

$users = User::whereIn('type', array(1, 2))->get();

$usersType_1 = $users->filter(function($item) {
   if($item->type == 1) {

       return $item->role()->attach(3);
   }
})
->all();

$usersType_2 = $users->filter(function($item) {
    if($item->type == 2) {

        return $item->role()->attach(4);
    }
})
->all();

Alternative :

$users = User::whereIn('type', array(1, 2))->get();

$usersType_1 = $users->filter(function($item) {
  $item->type == 1;
})
->all();

$usersType_2 = $users->filter(function($item) {
   return $item->type == 2;
})
->all();

$role1 = Role::find(3);
$role2 = Role::find(4);

$role1->users()->attach($usersType_1->puck('id'));

$role2->users()->attach($usersType_2->puck('id'));