I am working with a song, genre and artist model. The classes look like below:
class Genre < ActiveRecord::Base
has_many :song_genres
has_many :songs, through: :song_genres
has_many :artists, through: :songs
end
class Artist < ActiveRecord::Base
has_many :songs
has_many :genres, through: :songs
end
class Song < ActiveRecord::Base
belongs_to :artist
has_many :song_genres
has_many :genres, through: :song_genres
end
class SongGenre < ActiveRecord::Base
belongs_to :song
belongs_to :genre
end
The problem I having is when I assign a song (with a genre already assigned) to an artist, the genre isn't available to the artist instance through artist.genres
. Below is an example of what I mean:
song.genres << genre
=> [#<Genre:0x00007faf02b914b0 id: 2, name: "Pop">]
[10] pry(main)> song.genres
=> [#<Genre:0x00007faf02b914b0 id: 2, name: "Pop">]
[11] pry(main)> song.artist = artist
=> #<Artist:0x00007faf044cb048 id: 2, name: "James Blunt">
[12] pry(main)> artist.genres
=> []
Is this how ActiveRecord works? How can I get around this?
Okay, i got the problem here. You need to save
your song
record before calling artist.genres
. Genres will not be assigned to the related artist unless you save it.
> artist = Artist.new
=> #<Artist id: nil>
> artist.save
=> true
> song = Song.new
=> #<Song id: nil, artist_id: nil>
> song.artist = artist
=> #<Artist id: 1>
> genre = Genre.new
=> #<Genre id: nil>
> song.genres << genre
=> #<ActiveRecord::Associations::CollectionProxy [#<Genre id: nil>]>
# Before saving `song`
> artist.genres
=> #<ActiveRecord::Associations::CollectionProxy []>
> song.save
=> true
# After saving `song`
> artist.genres
=> #<ActiveRecord::Associations::CollectionProxy [#<Genre id: 1>]>
Let me know if it helps.