Storing related records with Extra attributes

I have three models

  • Playlists
  • Tracks
  • PlaylistTracks

Playlists

$this->hasManyToMany(
  "id",
  "PlaylistTracks",
  "playlist_id", "track_id",
  "Tracks",
  "id"
);

Tracks

$this->hasMany("id", "PlaylistTracks", "track_id");

PlaylistTracks

$this->belongsTo("track_id", "Tracks", "id");
$this->belongsTo("playlist_id", "Playlists", "id");

The playlistTracks table has and extra attribute called likes. Is there a way of setting this attribute without explicitly creating a new PlaylistTracks model.

This is what I have for creating a playlist with some tracks.

$playlist = new Playlists();
$playlist->setTitle('Test Playlist');

$tracks = array();
for($i = 1; $i < 10; $i++){
    $track = new Tracks();
    $track->setTitle('Track'. $i);
    //I whish I could just call this
    //$track->setLikes(10);
    $tracks[] = $track;
}

$playlist->tracks = $tracks;
$playlist->save();


34.0k

If you don't need to know who liked those tracks why don't you just add the likes column in tracks table ?

edited Sep '14

I don't want to show the total amount of likes of a track, but just the likes of a track in a playlist.



34.0k
edited Sep '14

Hm. In this case the quick and "normal" solution would be to add another model

playlistid | trackid | likes

with foreign keys and a unique key composed by playlistid and trackid

If you don't want to do this, maybe you will end up in doing messy things. You can use redis or some nosql db layer, add a public method or setter $likes to your Tracks model and implement:

    protected $likes;

    getLikes()
    {
         return $this->likes;
    }

    setLikes($likes)
    {
         $this->likes = $likes;
    }

    afterCreate()
    {
         $this->redis->save('track_'.$this->id.'_likes', $this->likes);
    }

    afterUpdate()
    {
         $likes = $this->redis->get('track_'.$this->id.'_likes');
         $this->redis->save('track_'.$this->id.'_likes', $this->likes + $likes);
    }

    afterFetch() 
    {
        $this->likes = $this->redis->get('track_ID_likes');
    }

Maybe that are tons of other solutions that i can not think right know ...