Michael Mano
Michael Mano

Reputation: 3440

Laravel 5.2 Relationship hasMany with another unique identifier

So I am learning laravel and trying to set up a blocked user list, for example if you want to block a user from viewing your profile you would block them, I have done this however I am just wondering if the way I have done it is correct.

Below is what I have done. My main question is, Is there another way to set up a identifier with out creating a new db field called unique_id where I would put both user ids in and then query it each time.

The Database Migration:

  Schema::create('blocked_users', function(Blueprint $table)
  {
      $table->increments('id');
      $table->integer('user_id')->unsigned();
      $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
      $table->integer('blocked_user_id')->unsigned();
      $table->foreign('blocked_user_id')->references('id')->on('users')->onDelete('cascade');
      $table->integer('unique_id')->unique();
      $table->text('reason')->nullable();
      $table->timestamps();
  });

The user model

public function BlockedUsers()
{
    return $this->hasMany('App\Models\User\BlockedUsers');
}

Then when I am blocking a user I enter the blocked users id and the current users id as the unique_id

and then this is the messy part which I am doing which I believe there should be an easier way.

if (BlockedUsers::whereUniqueId($user->id.Auth::user()->id)->exists()) {
    $blocked = 1;
 } else {
    $blocked = 0;
 }

I am trying to think of a way to set up a function in the user model to check if the user_id is = to the current user and the blocked_user_id is equal to the users profile id.

ALl i can think of is

public function isUserBlocked()
{
    return $this->hasOne('App\Models\User\BlockedUsers', 'blocked_user_id');
}

But obviously this would not work.

Upvotes: 1

Views: 278

Answers (1)

Ohgodwhy
Ohgodwhy

Reputation: 50787

I think you can just take care of this inside of some middleware applied to the route.

php artisan make:middleware UserCanViewProfile

Then we assume that the middleware will be applied to routes that have a Profile model, such as this:

Route::get('/profile/{profile}', 'ProfileController@show');

Now we'll fetch the instance of the profile in our middleware by accessing it through the route and then we'll check if the user has a block that contains the profile user id and the auth user id.

$profile = $this->route('profile');
$$block = BlockedUsers::where('user_id', $profile->user->id)->where('blocked_user_id', auth()->user()->id)->first();

if (empty($block)) {
    return $next($request);    
} else {
    abort(403, 'You are not allowed to view that profile!');
}

Of course you need to register this middleware in your App\Http\Kernel file under the $routeMiddleware, something like this:

'usercanviewprofile' => \App\Http\Middleware\UserCanViewProfile::class,

Then apply it to your routes

Route::group(['middleware' => ['usercanviewprofile'], 'prefix' => 'profile'], function(){
    Route::get('{profile}', 'ProfileController@show');
});

Or if you're using CRUD patterns:

Route::resource('profile', 'ProfileController')->middleware('usercanviewprofile');

Hopefully this helps.

Upvotes: 1

Related Questions