untymage's avatar

Advice for Relationship between Album and Artist (music stuff)

an album may have many Artists like this release :

https://open.spotify.com/album/4UpQlX9ApQ15vulTUJepwp

but the other hand a album may have only one artist like:

https://open.spotify.com/album/4TU8d9DGafZZiyN7peC4sl

I'd little confused about relationships, may i use belongToMany: Artist or BelongTo: Artist ?

0 likes
10 replies
Tray2's avatar

Depends a bit on how advanced you want to make it.

The KISS way.

Artist has many albums album belongs to artist

The less KISS way.

Artist has many albums Album has many artists

Then of course you can have track artists and so on .

I suggest starting with the kiss way in your tests then make it more advanced as you proceed.

I did this with books and I started with a single table and as the app progressed is created seperate tables and relations.

1 like
cmdobueno's avatar

I guess first I would go over what I know:

I know for sure an artist can have many albums

Additionally I know that an album can have many artists

My rough table structure (simplified for ease of description) would be like this:

Schema::create('albums', function ($table) {
    $table->increment('id');
    $table->string('name');
});
Schema::create('artists', function ($table) {
    $table->increment('id');
    $table->string('name');
});
Schema::create('album_artist', function ($table) {
    $table->unsignedInteger('album_id');
    $table->unsignedInteger('artist_id');

    $table->primary(['album_id','artist_id']);
    $table->foreign( 'album_id' )
        ->references( 'id' )
        ->on( 'albums' )
        ->onDelete( 'cascade' );
    $table->foreign( 'artist_id' )
        ->references( 'id' )
        ->on( 'albums' )
        ->onDelete( 'cascade' );
});

Then in my artists model

public function albums(){
    return $this->belongsToMany(Album::class,'album_artists');
}

Then my album model

public function getHasMultipleArtistsAttribute(){
    return $this->artists->count > 1;
}

public function getArtistAttribute(){
    if(  $this->artists->count > 1 ){
        return false;
    }else{
        return $this->artists()->first();
    }
}

public function artists(){
    return $this->belongsToMany(Artist::class);
}

I would then use some basic logic to decide if this belongs to a single or multiple artists when it comes to an album, which you can do by checking the length (count) of the artists relationship.

I feel that going about it considering only 1 artist per album would be more work than it would be worth, as you already know you want the ability to have multiple artists.

You could also have an option attribute on the album (i have the demonstrated in the model for album.. but this is of course optional

Nothing is highly optimized, but this is the general concept I would use for it... modifying the code as required.

1 like
Cronix's avatar

In @cmdobueno example, if you follow eloquent naming conventions and name the album_artists table to album_artist, then you wouldn't need to include the table name in the relationship definitions like here as laravel would be able to figure it out on its own $this->belongsToMany(Artist::class,'album_artists');

1 like
untymage's avatar

@cmdobueno Thanks, I will work on it, it's going very hard to me cuze the other side there is Track and Label Table, a Album hasmany tracks and a Label hasmany albums xD

cmdobueno's avatar

@Cronix @untymage

I have updated my answer to better follow naming conventions. That is important for sake of sanity later in your code.

1 like
WilliamBatsa's avatar

Nice: here is my advice: Start Simple and Iterate:

Comment on the wisdom of starting with a simple relationship structure (Artist has many albums; Album belongs to artist) and gradually evolving as the project progresses. Highlight the benefits of this iterative approach in terms of development ease and adaptability. KISS Principle:

Acknowledge the importance of the KISS principle (Keep It Simple, Stupid) in software development. Discuss how this principle advocates simplicity as a virtue, especially in the initial stages of development, and how it aligns with the idea of starting with a straightforward relationship. Database Flexibility:

Reflect on the mention of the "less KISS way" involving a many-to-many relationship. Discuss the potential benefits and complexities of this approach, emphasizing the importance of considering the specific needs of the application and the flexibility of the chosen database structure. ... spotypremium.com

440music's avatar

I know this is an old post but after 25 years of working with music and databases this is my advice: 4 tables table_1 artist table_2 album table_3 song title table_4 genre then create a relationship that connects songs to artist to album to genre I'm not an expert with databases but this has been working for me for15 years each of the tables

Please or to participate in this conversation.