staudenmeir / eloquent-has-many-deep

Laravel Eloquent HasManyThrough relationships with unlimited levels
MIT License
2.67k stars 157 forks source link

Session → many to many → Exercise → has many → Set with ->load('sessions') #155

Closed Yaranzo01 closed 2 years ago

Yaranzo01 commented 2 years ago
users
     - id
plans
     - id
     - user_id
sessions
     - id
     - plan_id
exercise
     - id
     - user_id
exercise_session
     - id
     - session_id
     - exercise_id
sets
     - id
     - exercise_id
     - session_id

I want to get sets, but not all sets for exercise_id from sets table, just sets from exercise from pivot (many to many) table. I am trying to get this from ->load('sessions') on Plan model.

I tested and it is returning all sets from exercise. I'm making mistake somewhere, but don't know where.

I can load just sets with everything provided in this package (If I need just sets without sessions/exercises), but I am trying to load plan with sessions -> with exercises (for each session) -> with sets (for exercises through pivot (so just for selected session)).

{
    use \Staudenmeir\EloquentHasManyDeep\HasRelationships;

    public function permissions()
    {
        return $this->hasManyDeep(Permission::class, ['role_user', Role::class]);
    }
}

Thanks in advance!

staudenmeir commented 2 years ago

I tested and it is returning all sets from exercise. I'm making mistake somewhere, but don't know where.

What relationship(s) did you test?

Yaranzo01 commented 2 years ago

I tested and it is returning all sets from exercise. I'm making mistake somewhere, but don't know where.

What relationship(s) did you test?

I tested every one of them (from your examples). As I can understand, from your example: many to many -> hasMany will work if I call that from Sessions.

If I add hasManyDeep (on Session) with pivot it will get sets from exercises defined in pivot, I can make this work. Also, I can make it work if I define custom pivot model with relationship defined for sets on that model (also from Session model).

But, I need this to work from Plan (as a parent/base model), or to work with ->load(). If I try to add session_id on sets, I am not able to provide session_id as parameter to sets through exercise_session pivot, from Plan as a parent/base model.

In other words, I am trying to make:

PLAN -> hasMany -> SESSION -> manyToMany -> EXERCISE -> hasMany SET

I would like to know if this is possible. If it is not possible, I will just recreate everything to get sets from session model. Thanks!

Yaranzo01 commented 2 years ago

I tested and it is returning all sets from exercise. I'm making mistake somewhere, but don't know where.

What relationship(s) did you test?

I tested every one of them (from your examples). As I can understand, from your example: many to many -> hasMany will work if I call that from Sessions.

If I add hasManyDeep (on Session) with pivot it will get sets from exercises defined in pivot, I can make this work. Also, I can make it work if I define custom pivot model with relationship defined for sets on that model (also from Session model).

But, I need this to work from Plan (as a parent/base model), or to work with ->load(). If I try to add session_id on sets, I am not able to provide session_id as parameter to sets through exercise_session pivot, from Plan as a parent/base model.

In other words, I am trying to make:

PLAN -> hasMany -> SESSION -> manyToMany -> EXERCISE -> hasMany SET

I would like to know if this is possible. If it is not possible, I will just recreate everything to get sets from session model. Thanks!

With my current knowledge I think that it is not possible to get this with eager loading. It is possible to get all up to Sets, but not Sets itself. The reason for this is the inability of framework to do relationships with 2x foreign keys at the same time. So to save everyone some time, you ll' need to do this separately.

staudenmeir commented 2 years ago

Do you mean like this?

class Plan extends Model
{
    use \Staudenmeir\EloquentHasManyDeep\HasRelationships;

    public function sets()
    {
        return $this->hasManyDeep(Set::class, [Session::class, 'exercise_session', Exercise::class])
            ->whereColumn('sets.session_id', '=', 'exercise_session.session_id');
    }
}
Yaranzo01 commented 2 years ago

Do you mean like this?

class Plan extends Model
{
    use \Staudenmeir\EloquentHasManyDeep\HasRelationships;

    public function sets()
    {
        return $this->hasManyDeep(Set::class, [Session::class, 'exercise_session', Exercise::class])
            ->whereColumn('sets.session_id', '=', 'exercise_session.session_id');
    }
}

Yes, that is it. It is working great. I didn't know that I can attach ->whereColumn('sets.session_id', '=', 'exercise_session.session_id').

Thanks a lot for your help!