Support the ongoing development of Laravel.io →
posted 10 years ago
Eloquent

Workout app

Hello, im working on a workout app and I want to set up my relationships.

For example:

  • An User can have many routines
  • A Routine has a name and must have 7 workout days (i can set up the 7 days and edit those later)
  • A WorkoutDay has x number of sets
  • A Set has x number of excercises
  • An Excercise has a name, #of reps and #of times

I was setting up the very first things and got into this:

I am using laravel 5 default user migration only changed PK to user_id

User.php

<?php namespace App;

use Illuminate\Auth\Authenticatable;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Auth\Passwords\CanResetPassword;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract;

class User extends Model implements AuthenticatableContract, CanResetPasswordContract {

	use Authenticatable, CanResetPassword;

	/**
	 * The database table used by the model.
	 *
	 * @var string
	 */
	protected $table = 'users';

	/**
	 * The database table primary key.
	 *
	 * @var string
	 */
	protected $primaryKey = 'user_id';

	/**
	 * The attributes that are mass assignable.
	 *
	 * @var array
	 */
	protected $fillable = ['name', 'email', 'password'];

	/**
	 * The attributes excluded from the model's JSON form.
	 *
	 * @var array
	 */
	protected $hidden = ['password', 'remember_token'];

	//relationships

	/**
	 * An User can have many Routines
	 * @return mixed
	 */
	public function routines()
	{
		return $this->hasMany('App\Routine');
	}

}

Routine.php

<?php namespace App;

use Illuminate\Database\Eloquent\Model;

class Routine extends Model {

	/**
	 * The database table used by the model.
	 *
	 * @var string
	 */
	protected $table = 'routines';

	/**
	 * The database table primary key.
	 *
	 * @var string
	 */
	protected $primaryKey = 'routine_id';

	/**
	 * The attributes that are mass assignable.
	 *
	 * @var array
	 */
	protected $fillable = [
		'name',
		'user_id',
	];

	//relationships

	/**
	 * A Routine is owned by an User.
	 *
	 * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
	 */
	public function user()
	{
		return $this->belongsTo('App\User');
	}
}

Until here it worked as expected.

I tried to set up the second relationship by doing this:

1.- Created the table

Schema::create('workout_days', function(Blueprint $table)
		{
			$table->increments('day_id');
			$table->integer('routine_id')->unsigned();
			$table->enum('type', ['WORK', 'OFF']);
			$table->tinyInteger('day_number');
			$table->timestamps();

			$table->foreign('routine_id')->references('routine_id')->on('routines')->onDelete('cascade');
		});

The WorkoutDay Model:

<?php namespace App;

use Illuminate\Database\Eloquent\Model;

class WorkoutDay extends Model {

	/**
	 * The database table used by the model.
	 *
	 * @var string
	 */
	protected $table = 'workout_days';

	/**
	 * The database table primary key.
	 *
	 * @var string
	 */
	protected $primaryKey = 'day_id';

	/**
	 * The attributes that are mass assignable.
	 *
	 * @var array
	 */
	protected $fillable = [
		'routine_id',
		'type',
		'day_number',
	];

	//relationships

	/**
	 * A WorkoutDay is owned by a Routine.
	 *
	 * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
	 */
	public function routine()
	{
		return $this->belongsTo('App\Routine');
	}
}

Added this to Routine.php

        /**
	 * A Routine can have many WorkoutDays
	 *
	 * @return mixed
	 */
	public function workoutdays()
	{
		return $this->hasMany('App\WorkoutDay');
	}

Then tested using 'php artisan tinker' and got this:

$user = App\User::first(); //I only have one user so this wont change from this User::find(1);
$user->routines; //it showed the routines I setted up to the user
//then trying to do this:
$user->routines->workoutdays; //Undefined property: Illuminate\Database\Eloquent\Collection::$workoutdays on line 1 -- When calling routines, do i get a collection?
//also tried 
$user->routines()->workoutdays; //didnt worked
//also tried 
$user->routines()->workoutdays(); //errors poppin everywhere.

Thanks in advance

Last updated 3 years ago.
0

You can display workoutdays for routines that belongs to user this way

$routines = $user->routines;
@foreach ($routines as $routine)
   /* here you can use $routine->workoutdays */
@endforeach

In

$user->routines->workoutdays;

you are trying to get collection property from collection, it is not possible.
If user had only one routine it will be possible, so you need to iterate through the user routines and display workout days for each routine separately.

Last updated 10 years ago.
0

Sign in to participate in this thread!

PHPverse

Your banner here too?

Jackpump jackpump Joined 16 Nov 2014

Moderators

We'd like to thank these amazing companies for supporting us

Your logo here?

Laravel.io

The Laravel portal for problem solving, knowledge sharing and community building.

© 2025 Laravel.io - All rights reserved.