hasMany Relationship not working

Published 9 months ago by JokersMild85

A workout has many workout_exercises:

Workout Model:

class Workout extends Model
{
    //
    protected $fillable = [
        'user_id',
        'name',
        'published_at'
    ];
    
    public function workout_exercises()
    {
        return $this->hasMany('App\WorkoutExercise');
    }
    
    public function user()
    {
        return $this->belongsTo('App\User');
    }
}

A workout_exercise belongs to a workout

Workout_Exercise Model

class WorkoutExercise extends Model
{
    //
    protected $fillable = [
        'workout_id',
        'exercise_id',
        'we_set_num',
        'we_rep_num',
        'we_set_complete',
    ];
    
    public function workout(){
        return $this->belongsTo('App\Workout');
    }

    public function exercise(){
        return $this->belongsTo('App\Exercise');
    }
}

When I define my $workout object and then run the following statement, I receive a 'trying to get property on non-object' error

$workout->workout_exercises->get();

Any suggestions?

Best Answer (As Selected By JokersMild85)
bobbybouwmann

Select won't work here because you always need to select the foreign key of the relation! That is key part of relations.

return $this->hasMany('App\WorkoutExercise')->select('column_name', 'column_name');

Anyway the link to the documentation has everything you need! If you still have questions let me now!

bobbybouwmann

You can't call get on your relationship. You can find a lot of examples in the documentation for this:

Documentation: https://laravel.com/docs/5.5/eloquent-relationships#one-to-many

JokersMild85

So how would I retrieve all of the workout_exercises of $workout? The example provided in the documentation still give me the same error?

JoaoPedroAS51

You need to do a foreach first:

foreach($workout->workout_exercises as $workout_exercise)
{
    $workout_exercise->something;
}

//Blade
@foreach($workout->workout_exercises as $workout_exercise)
    {{ $workout_exercise->something }}
@endforeach 
geraintp
$workout->workout_exercises;

returns the collection

$workout->workout_exercises();

returns the builder query object, which you can chain to add too, to change the query and call get() at the end to return the collection.

return $workout->workout_exercises()->get();

==

return $workout->workout_exercises;

JokersMild85
$workout->workout_exercises->all();

This worked but is there a way I can return specific columns instead of all of them?

JoaoPedroAS51

Try:

$workout->workout_exercises->select('column_name', 'column_name')->get();
JokersMild85

select isn't a usable method in Eloquent

JoaoPedroAS51

Do you always want to return specific columns?

If yes you can do this:

public function workout_exercises()
    {
        return $this->hasMany('App\WorkoutExercise')->select('column_name', 'column_name');
    }
Snapey
Snapey
9 months ago (998,255 XP)

select isn't a usable method in Eloquent

who says?

JokersMild85

It works in QueryBuilder but if I use it in a statement like I'm trying to now, that's the error in receiving.

bobbybouwmann

Select won't work here because you always need to select the foreign key of the relation! That is key part of relations.

return $this->hasMany('App\WorkoutExercise')->select('column_name', 'column_name');

Anyway the link to the documentation has everything you need! If you still have questions let me now!

Snapey
Snapey
9 months ago (998,255 XP)

If you sometimes want a subset of the columns, you can create an extra relationship that has the selects applied and give it a different name.

Please sign in or create an account to participate in this conversation.