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();


35.1k

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.



35.1k
edited Sep '14

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

playlist_id | track_id | likes

with foreign keys and a unique key composed by playlist_id and track_id

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 ...