skip to Main Content

Is there any way to create a relationship on a Laravel model using an "OR" condition for the field used to join the table while loading an eloquent model?

Example Table: user_connections

Name Type
id bigInt|primary|auto_increment
from_user_id bigInt
to_user_id bigInt
created_at timestamp?
updated_at timestamp?

If I have a Laravel Model named UserConnection that uses the above table schema, is there any way to define a relationship on that model that can utilize either the from_user_id field OR the to_user_id field.

The goal is to have a relationship named userConnections on a User model that can be tied to either field.

Example of Desired Syntax:

class User {
...

// THE RELATIONSHIP METHOD NAME TO USE (DOESN'T HAVE TO BE `hasMany`)
public function userConnections(){
    return $this->hasMany(
        AppModelsUserConnection::class, /* THE TARGET CLASS TO BE LOADED */
        'from_user_id||to_user_id',        /* JOIN ON EITHER OF THESE FIELDS */
        'id'                               /* THE ID OF THE USER IN THIS MODEL */
    );
}

I know I can do this with a query and load the models manually. But I want to stick to the Laravel format for relationships so that other people on this project can use the relationship naturally.

Please don’t bother responding if your answer is going to be "Don’t structure the database that way", because I cannot change the schema. I need to figure out how to make it work with this schema.

My concept isn’t set in stone like the schema is, but it should illustrate what I’m trying to achieve. I am entirely open minded to any solution that works with this db schema.

Hoping someone else has run into a similar issue and might have a solution.

Thanks in advance to anyone who has read this far.

2

Answers


  1. I’m not sure. Is this what you were asking for?

    UserConnection::where(function ($query) {
        $query->where('from_user_id', $this->id)
              ->orWhere('to_user_id', $this->id);
    });
    

    You can combine it with Laravel Attribute for a single call.

    public function userConnectionsQuery()
    {
        return UserConnection::where(function ($query) {
            $query->where('from_user_id', $this->id)
                  ->orWhere('to_user_id', $this->id);
        });
    }
    
    public function getUserConnectionsAttribute()
    {
        return $this->userConnectionsQuery()->get();
    }
    

    This will work like this

    $user = User::find($userId);
    
    $userConnections = $user->userConnectionsQuery()->get(); # Directly call
    $userConnections = $user->userConnectionsQuery()->where('created_at', '>', $someDate)->get(); # Directly call
    $userConnections = $user->userConnections; # Dynamic Access
    
    Login or Signup to reply.
  2. public function connections()
    {
        return $this->hasMany(UserConnection::class, function ($query) {
            $query->where('from_user_id', $this->id)
                  ->orWhere('to_user_id', $this->id);
        });
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search