1

I have 2 channels set up: Channel A and Channel B. I also have public registration so users can log in and fill out two forms (Form A and Form B), each form creating an entry in their respective channel with the user as the author. The user can only create an entry in Channel B if they already have an entry in Channel A.

To get all the users who have an entry in Channel A but not in Channel B, I tried writing something like this in my class:

public function getUsersWithoutChannelBEntry()
{
    $channel_A_entries = Entry::find()
        ->sectionId(1)
        ->all();

    $userIds = [];
    foreach ($channel_A_entries as $entry) {

        $channel_B_entry_exists = Entry::find()
            ->sectionId(2)
            ->authorId($entry->authorId)
            ->exists();

        if (! $channel_B_entry_exists) {
            $userIds[] = $entry->authorId;
        }

    }

    return User::find()
        ->id($userIds)
        ->all();
}

However, this creates an N+1 problem. I have roughly 200 users, so potentially 200 entries in either channel, and thus a lot of db queries and a substantially larger load time.

As an alternative approach, I've also tried looping through Channel A, adding each author ID into an array (Array A), then doing the same with Channel B making Array B. Then I use array_diff() to extract the author IDs that are in Array A but not in Array B. However, this still causes a bit of long load time.

I've looked into eager loading, but that seems to only apply to related fields.

Is there a more efficient way to get all users who authored a Channel A entry but not Channel B entry?

1

There's one bit missing in the constrains you explain above, do users end up with 1 entry only per channel so a total of 2 posts max?

If so, we know that:

  • each users can have a max of 2 posts
  • a user cannot post in B is they haven't completed their post in A

So assuming this first condition is also true (2 entries/user) you could just loop through users post count looking for those with less than 2 posts and they would automatically be the users who haven't posted in B..? Just a shot in the dark :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.