Skip to content

Instantly share code, notes, and snippets.

@MECU
Last active May 19, 2016 09:21
Show Gist options
  • Save MECU/f0f8348e24b75893f4f5acdaf2a920b7 to your computer and use it in GitHub Desktop.
Save MECU/f0f8348e24b75893f4f5acdaf2a920b7 to your computer and use it in GitHub Desktop.
OneToMultipleMany DB Schema
(Simplified schema)
CREATE TABLE season
(
id INT(10) UNSIGNED PRIMARY KEY NOT NULL AUTO_INCREMENT,
year YEAR(4) NOT NULL,
teamid SMALLINT(5) UNSIGNED NOT NULL,
levelid TINYINT(3) UNSIGNED,
divid MEDIUMINT(9),
district TINYINT(4),
);
CREATE TABLE game
(
gameid INT(11) UNSIGNED PRIMARY KEY NOT NULL AUTO_INCREMENT,
hometeam SMALLINT(5) UNSIGNED NOT NULL,
awayteam SMALLINT(5) UNSIGNED NOT NULL,
homescore TINYINT(4) UNSIGNED NOT NULL,
awayscore TINYINT(4) UNSIGNED NOT NULL,
date DATE DEFAULT '0000-00-00' NOT NULL,
time TIME DEFAULT '00:00:00' NOT NULL,
);
What I have to do (which doesn't allow eagar loading) in a controller:
// Load Season
$season = Season::where(['teamid' => $team, 'year' => $year])->first();
// Load Games (not eager)
$away = Game::where(['awayteam' => $team])
->whereBetween('date', [$start, $end])
->orderBy('date')
->get();
$home = Game::where(['hometeam' => $team])
->whereBetween('date', [$start, $end])
->orderBy('date')
->get();
$games = $away->merge($home)->sortBy('date');
What would be awesome in Season model:
public function games()
{
return $this->hasMultipleMany(['App\Team', 'hometeam', 'teamid'], ['App\Team', 'awayteam', 'teamid']);
}
$season = Season::where(['teamid' => $team, 'year' => $year])->with('games')->first();
@taylorotwell
Copy link

I'm confused. Why not put "season_id" on the games table, then in seasons model do:

games()
{
    return hasMany(Game::class, 'season_id');
}

@MECU
Copy link
Author

MECU commented May 18, 2016

Each game as 2 teams, each team has their own Season.

@taylorotwell
Copy link

taylorotwell commented May 18, 2016

So, in season, can you do:

games()
{
    return $this->hasMany('Game', 'hometeam')->orWhere('awayteam', $this->team_id);
}

@MECU
Copy link
Author

MECU commented May 18, 2016

It does work, but the resulting query isn't fully accurate:

select * from `game` where `game`.`deleted_at` is null and `game`.`hometeam` = '14' and `game`.`hometeam` is not null or `awayteam` = '14'

Since the or condition thusly ignores the deleted_at is null (important) and there is no check for awayteam is not null.

Also, I'd want to further qualify the conditions (a date range specifically) so perhaps there is no (good/easy?) relationship way to handle this case and I do just need to have a query.

@jrmadsen67
Copy link

Can you write the raw sql you would like to see, just to "test" against what I am writing as an attempt?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment