Search code examples
laraveleloquent-relationship

Laravel associate relationships by model instance dynamically


In my Laravel 9 project, My User Model is belongs to 3 models (Distributor, Agency and Advertiser) like:

public function distributor()
{
    return $this->belongsTo(Distributor::class);
}

public function agency()
{
    return $this->belongsTo(Agency::class);
}

public function advertiser()
{
    return $this->belongsTo(Advertiser::class);
}

And I use this function to associate in my DistributorRepository(and other 2 model's repositories):

public function associateUser($id, $user_id)
{
    $user        = $this->user->find($user_id);
    $distributor = $this->find($id);
    $result      = $user->distributor()->associate($distributor)->save();
    return $result;
}

Now, I want to modify to associate them by user's id and relation model instance (Distributor, Agency and Advertiser) in my UserRepository (or UserService) dynamically, like:

public function associate($id, $modelInstance)
{
    // Something happens here
}

Is that possible and how to do? Thanks!


Solution

  • If I understand right, then you can do it with:

    public function associate($user_id, $parentModelInstance)
    {
        $user = User::find($user_id); //or how ever you get user in repository
        $reflect = new ReflectionClass($parentModelInstance);
        $relationName = Str::lower($reflect->getShortName()); //magic for getting relation (if class name is relation name)
    
        return $user->{$relationName}()->associate($parentModelInstance)->save();
    }
    

    And you can use it like this:

    $distributor = Distributor::find(1);
    $user_id = 1;
    
    $this->associate($user_id, $distributor)