CedricBongaerts's avatar

Group table creating a unique invite code or invite methode

I'm making an App where Users can join groups but I'm trying to find a methode on how the users can join the group through the site by an invite code.

My idea was for the group to create a unique invite code when it's created. If a user that is logged in, was to put the invite code into 'a join group' text area and press join, the connection through the pivot table would automaticly be created.

Is this a good idea? If so, how would I create the unique invite code for that specific groups table once it was created.

Any other tips are welcome!

Thanks, Cedric

0 likes
5 replies
Kryptonit3's avatar

Another approach would be to allow anyone to join the group, but add a column $table->boolean('approved')->default(false) and then a member of the group (admin/owner?) would see a list of pending users and could approve them that way. Then there is no need to mess with copy/paste random alpha_num strings.

If you go the approach of an invite code you will then need to decide if it will be time based, or quantity based for how many people can join based off of the invite logic.

I guess it all depends on your app and how the groups matter.

CedricBongaerts's avatar

@Kryptonit3 Well the groups are going to be private. The registered users aren't supposed to be able to see the other groups. That's why I'm thinking of this methode. The creator of the group doesn't have to be the owner/creator either, there is no use for it.

Update: Also, I would make it a timebased invite code, but how can that be done? I'm sorry for all these questions, I'm quite new to all of this.

Thanks

Kryptonit3's avatar

You say there is no creator so I assume that you manage all groups?

You would have something like this

// TABLES
Schema::create('groups', function (Blueprint $table) {
    $table->increments('id');
    $table->string('name');
    $table->timestamps();
});

Schema::create('invites', function (Blueprint $table) {
    $table->increments('id');
    $table->integer('group_id')->unsigned();
    $table->foreign('group_id')->references('id')->on('groups')->onCascade('update')->onDelete('update');
    $table->string('code')->unique();
    $table->timestamp('expires_at');
    $table->timestamps();
});

You will need to add relation and pivot table for User->belongsToMany('\App\Group') and vice-versa for Group

// Group Model
<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Group extends Model
{
    protected $fillable = ['name'];

    public function invites()
    {
        /*
        *   in case you want to give them out individually.
        *   if you just want to have one for everyone then make it
        *   hasOne and change function to invite()
        */
        return $this->hasMany('\App\Invite');
    }

}
// Invite Model
<?php

namespace App;

use Illuminate\Database\Eloquent\Model;
use Carbon\Carbon;

class Invite extends Model
{
    protected $fillable = ['group_id', 'code', 'expires_at'];
    
    protected $dates = ['expires_at'];

    public function group()
    {
        return $this->belongsTo('\App\Group');
    }
    
    // check if invite is expired
    public function expired()
    {
        $status = (Carbon::now() > $this->expires_at) ? true : false;
        
        return $status;
    }

    public static function generate()
    {
        $exists = true;
        while ($exists) {
            $code = str_random(15);
            $check = self::where('code', $code)->first();
            if( ! $check->count()){
                $exists = false;
            }
        }
        return $code;
    }

}

Example of invite creation

use Carbon\Carbon;

$group = Group::find(1); // Group ID you want to manage
$code = Invite::generate();
$invite = $group->invites()->create([
    'code' => $code,
    'expires_at' => Carbon::now()->addDays(7) // invite expires in 7 days
]);

Then to check invite

$code = 'my-invite-code';
$invite = Invite::where('code', $code)->get();

if ($invite->expired()) {
    session()->flash('error', 'This invite is expired!');
    return redirect()->back();
}
// invite is not expired, add user to group and delete invite

This is just a sample.

CedricBongaerts's avatar

@Kryptonit3 Well the user that creates the group, gets access to the invite code but he/she does not need to be an administrator. Once a second user joins the group through the invite code, he/she has the same access to everything in the group.

I tried everything stated above. Error fix #1: was with the 'php artisan migrate' where I had to change the:

->onDelete('update')

To:

->onDelete('cascade')

Then, I ran into an error when trying to create the invite code. This is how I am testing out the code: I simply made a Group to test it out (has the id=1).

In my GroupController.php I added a 'createInvite' function like this:

use App\Group;
use App\Invite;
use App\Http\Requests;
use App\Http\Controllers\Controller;

use Illuminate\Http\Request;

use Carbon\Carbon;

class GroupController extends Controller {
....
public function createInvite()
    {
        $group = Group::find(1); // Group ID you want to manage
        $code = Invite::generate();
        $invite = $group->invites()->create([
            'code' => $code,
            'expires_at' => Carbon::now()->addDays(7) // invite expires in 7 days
        ]);
        return 'invite code created';   
    }
...
}

and in my routes.php page trigger the function through the link '/invite by doing this:

$router->post('invite', ['as' => 'invite.create', 'uses' => 'GroupController@createInvite']);

But when doing this, I got this error: FatalErrorException in Invite.php line 31: Call to a member function count() on a non-object

Error fix #2:

public static function generate()
    {
        $exists = true;
        while ($exists) {
            $code = str_random(15);
            $check = self::where('code', $code)->first();
            if( ! $check){  // <-- Error
                $exists = false;
            }
        }
        return $code;
    }

To fix the error stated above I removed the '->count()'

Now I'm getting a 'MethodNotAllowedHttpException in RouteCollection.php line 207:' I've created a new post seeing this is more of a Code Review. This is the link: https://laracasts.com/discuss/channels/code-review/methodnotallowedhttpexception-in-routecollectionphp-line-207-2

Kryptonit3's avatar

yeah, both onUpdate and onDelete need to be cascade. None of the code was tested, it was more me just posting my thought process.

Please or to participate in this conversation.