How to model the concept of "Featuring" (ie when an artist is "shown" on a song)

Sometimes there may be more than one artist per song. For example, Jay-z's new song "A Star Is Born" includes the artist Cole and will thus appear as "Jay-z (featuring Cole) -" A Star Is Born "in the catalog. My question is how to simulate this in my database.

It's pretty simple now: every song belongs_to :artist

and every artist has_many :songs

. I want to change this so that there are many artists in the songs, with one artist listed as "primary" ie. If A, B, and C are associated with a given song, and A is the primary, the artist for that song will be displayed as "A (featuring B and C)".

That's what I think:

Song:

has_many :artists, :through => :performances

      

Executor:

has_many :songs, :through => :performances

      

where the model performance

would have one field for primary?

, determining if a given performance is the "main" performance in the song, meaning that the artist associated with that performance is the main performer of the song.

Does this approach make sense?

+2


source to share


2 answers


Yes. You nailed it.



+2


source


It looks like you are using the performances as a join table with added information to link songs to artists. But that doesn't work well enough. Songs can have multiple performances, and each performance can have multiple artists.

I would restructure the database to use the following structure. Unfortunately it takes a little more work to add the Song to the database, but it allows for covers, multiple versions of the song and duets.

Song (Attributes: Title)

  • has many designs
  • has many performers (through execution)
  • has many artists (via performers)

Performance (foreign key: Song_id, attributes: date, year, length, genre, album)

  • belongs to Song
  • has many performers
  • has many performers (through performers)


Artists (Foreign Keys: Performance_id, Artist_id, Attributes: Role)

  • has one song (via artists) NB has_one: via is not a core feature of Rails
  • belongs to execution
  • owned by Artist

Artist (attributes: name, date of birth, etc.) (other personal data)

  • has many performers
  • has many performances (through performers)
  • has many songs (through performance)

If you want to force 1 main performer / performance, it will be done as confirmation in Performers.

class Performers < ActiveRecord::Base
  validates_uniqueness_of :role, :scope => [:performance_id], :if => Proc.new{|performer| performer.role == "primary"}
end

      

+1


source







All Articles