Search code examples
laraveleloquentlaravel-8laravel-relations

Laravel relationship with additional where statement


I know I can define a relationship by

Class Users extends Model{
   
   function profile(){
      return $this->hasOne(Profile::Class);
   }
}

is there a way like adding extra query to the relationship like other than foreign key and local key that is available to define, I want to only get those records of Profile model that field active contains a value of 1. Profile model has a field named active. Any help, ideas is greatly appreciated, thank you in advance.


Solution

  • you can simply try

    return $this->hasOne(Profile::Class)->where('active', 1);
    

    but better approach will be using Scope like this.

    1. create a folder app/Scopes and add a new file ActiveUserOnly.php

    2. place this code there

      namespace App\Scopes;
      
      use \Illuminate\Database\Eloquent\Builder;
      use \Illuminate\Database\Eloquent\Scope;
      use \Illuminate\Database\Eloquent\Model;
      
      class ActiveUsersOnly implements Scope {
          /**
           * @inheritdoc
           *
           * @param Builder $builder
           * @param Model $model
           *
           * @return Builder|void
           */
          public function apply( Builder $builder, Model $model ) {
              return $builder->where( 'active', '=', true );
          }
      }
      
    3. add this code to the top of Profile model.

       use App\Scopes\ActiveProfilesOnly;
      

    add this code in your Profile model.

        protected static function boot() {
            parent::boot();
            static::addGlobalScope( new ActiveProfilesOnly() );
        }
    
    1. then this code will work in your User model.

       Class Users extends Model{
      
          function profile(){
             return $this->hasOne(Profile::Class);
      
      
           }
       }