1

I am having a hard time finding a solution. If anyone could help me would be a great help. Let's say I have a user table like:

id name
1 john
2 brian
3 eddy
4 mia

and pivot table for group_user:

groupid userid
1 1
1 2
1 3
2 2
2 3
2 4

And when a new meeting is created(after fill up a form), I want to assign them a user in every meeting like this in meeting table:

meetingid groupid userid
1 1 1
2 1 2
3 1 3
4 1 1
5 1 2
6 2 2
7 2 3
8 2 4
9 2 2
10 2 3

This is my model: User.php

class User extends Authenticatable
{
    use SoftDeletes;
    use HasApiTokens;
    use HasFactory;
    use HasProfilePhoto;
    use Notifiable;
    use TwoFactorAuthenticatable;

    /**
     * The attributes that are mass assignable.
     *
     * @var string[]
     */
    protected $fillable = [
        'name',
        'email',
        'password',
        'role'
    ];
    protected $dates = ['deleted_at'];
    public function grp()
    {
    return $this->belongsToMany(Group::class);
    }

    /**
     * The attributes that should be hidden for serialization.
     *
     * @var array
     */
    protected $hidden = [
        'password',
        'remember_token',
        'two_factor_recovery_codes',
        'two_factor_secret',
    ];

    /**
     * The attributes that should be cast.
     *
     * @var array
     */
    protected $casts = [
        'email_verified_at' => 'datetime',
    ];

    /**
     * The accessors to append to the model's array form.
     *
     * @var array
     */
    protected $appends = [
        'profile_photo_url',
    ];
}

Group.php

class Group extends Model
{
    use SoftDeletes;
    use HasFactory;
    public $timestamps=true;
    protected $dates = ['deleted_at'];
    public function creators()
    {
    return $this->belongsToMany(User::class);
    }
}

Meeting.php

class Meeting extends Model
{
    use HasFactory;
    public function gr()
    {
    return $this->belongsTo('App\Models\Group','groupID');
    }
}

So, for every meeting created for the group, one user in that group will be auto assigned to that meeting in round robin algorithm. If my details is not enough please tell me, I will try my best to provide it. Thanks in advance.

EDIT: what if i want to declare in this public function? it is possible?

public function addsession(Request $req)
    {
       $mod = null;
    $latestUserId=Meeting::where('groupID', $req->groupID)
    ->latest('id')
    ->first()
    ?->meetingModerator;

    //the first meeting or all the users have already had their turn
    $firstUserId=DB::table('group_user')
    ->where('group_id', $req->groupID)
    ->orderBy('user_id')
    ->first()
    ?->user_id;

    //second time meeting is being held
    if ($latestUserId) {
    $nextUserId=DB::table('group_user')
        ->where('group_id', $req->groupID)
        ->where('user_id', ">", $latestUserId)
        ->orderBy('user_id')
        ->first()
        ?->user_id;
    $mod = $nextUserId;
    } else {
    $mod = $firstUserId;
    }
        
        $data = new Meeting;
        $data->groupID = $req->groupID;
        $data->meetingDate = $req->meetingDate;
        $data->meetingTime = $req->meetingTime;
        $data->meetingDesc = $req->meetingDesc;
        $data->meetingLink = $req->meetingLink;
        $data->meetingModerator = $mod;
        $file = $req->meetingNotes;
        $filename = time().'.'.$file->getClientOriginalExtension();
        $req->meetingNotes->move('assets/file',$filename);
        $data->meetingNotes=$filename;
        $data->save();
return redirect('redirect');
}

1 Answers1

0

I would probably do this by fetching the user ID for the latest meeting for that specific group:

private function getLatestUserId(int $groupid): ?int
{
    return Meeting::where('groupid', $groupid)
        ->latest('meetingid')
        ->first()
        ?->user_id;
}

Then using that user ID I would figure out who is the next user in that group:

private function getNextUserId(int $groupid, int $latestUserId): ?int
{
    return DB::table('group_user')
        ->where('groupid', $groupid)
        ->where('user_id', ">", $latestUserId)
        ->orderBy('user_id')
        ->first()
        ?->user_id;
}

If this is the first meeting or all the users have already had their turn, I would start with the first user in that group:

private function getFirstUserId($groupid): ?int
{
    return DB::table('group_user')
        ->where('groupid', $groupid)
        ->orderBy('user_id')
        ->first()
        ?->user_id;
}

As for where this would happen, I would have a service class injected in to the controller. This service class would be responsible for handling the logic for creating and updating Meetings.

Edit:

How all this would look together:

public function getMeetingUserId(int $groupid): ?int
{
    $latestUserId = $this->getLatestUserId($groupid);
    if ($latestUserId === null) {
        // First time the meeting is being held
        return $this->getFirstUserId($groupid);
    }

    $nextUserId = $this->getNextUserId($groupid, $latestUserId);
    if ($nextUserId === null) {
        // All users have had their turn, starting over
        return $this->getFirstUserId($groupid);
    }

    return $nextUserId;
}

Edit 2:

I recommend doing it like in the example above on the first edit, but ...

$mod = null;

$latestUserId=Meeting::where('groupID', $req->groupID)
    ->latest('meetingid')
    ->first()
    ?->user_id;

$firstUserId=DB::table('group_user')
    ->where('group_id', $req->groupID)
    ->orderBy('user_id')
    ->first()
    ?->user_id;

if ($latestUserId) {
    $nextUserId=DB::table('group_user')
        ->where('group_id', $req->groupID)
        ->where('user_id', ">", $latestUserId)
        ->orderBy('user_id')
        ->first()
        ?->user_id;
    $mod = $nextUserId;
} else {
    $mod = $firstUserId;
}
  • what if i use all this code but under one public function? how can i call them? do i need to apply if statement? – ftnsyhrah14 Apr 19 '22 at 14:06
  • Hello, I added an example of how it would be used – Michael Grove Apr 19 '22 at 14:57
  • I have edit my question, I would appreciate if you take a look. – ftnsyhrah14 Apr 19 '22 at 15:58
  • Hello, I added an alternative way of doing it – Michael Grove Apr 19 '22 at 16:12
  • for this line `latest('meetingModerator')` it search for the latest meeting right? so supposedly i put the id or date? – ftnsyhrah14 Apr 19 '22 at 18:09
  • i already try to run with your code, but when i create the second meeting, it still picks the first user_id, i put my updated code up there – ftnsyhrah14 Apr 19 '22 at 18:34
  • Ah, my mistake. I updated my answer again. It's supposed to be ```latest('meetingid')```. That way the meetings are ordered based on which one is newest. – Michael Grove Apr 20 '22 at 13:11
  • As for the code, in your question you wrote that the meeting table has an the user ID column with and underscore (```user_id```), but the ```group_user``` table has it without, like so: ```userid```, so you want to update that as well. – Michael Grove Apr 20 '22 at 13:13
  • I already try to run the code but i managed to select for one round only where all the users have already had their turn, but the the next meeting to select the first user, it become null, i dont know what is wrong – ftnsyhrah14 Apr 21 '22 at 13:39