Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Saving join attributes through a has_many :through with :conditions

I have an Artist model that looks like this:

# app/models/artist.rb
class Artist < ActiveRecord::Base
  # Relationships
  has_many  :releases
  has_many  :songs, :through => :releases
  has_many  :featured_songs,  :through => :releases,
                              :class_name => "Song",
                              :source => :song,
                              :conditions => { 'releases.featured', true }                         

end

Retrieving the featured_songs works perfectly. The issue here is I'm unable to add a new featured_song to an artist because for some reason the 'featured' attribute is set to 'nil'.

This is what I'm attempting:

ruby-1.9.2-p180 :004 > a = Artist.first
ruby-1.9.2-p180 :005 > a.featured_songs.create(:title => "Title", :user => User.first)

The actual result of that is:

ruby-1.9.2-p180 :004 > a = Artist.first
ruby-1.9.2-p180 :005 > a.featured_songs.create(:title => "Title", :user => User.first)
  User Load (0.9ms)  SELECT `users`.* FROM `users` LIMIT 1
  SQL (1.0ms)  BEGIN
  SQL (5.5ms)  INSERT INTO `songs` (`created_at`, `title`, `updated_at`, `user_id`) VALUES (?, ?, ?, ?)  [["created_at", Thu, 11 Aug 2011 18:30:34 UTC +00:00], ["title", "Title"], ["updated_at", Thu, 11 Aug 2011 18:30:34 UTC +00:00], ["user_id", 1]]
  SQL (1.2ms)  INSERT INTO `releases` (`album_id`, `artist_id`, `created_at`, `featured`, `song_id`, `updated_at`) VALUES (?, ?, ?, ?, ?, ?)  [["album_id", nil], ["artist_id", 1], ["created_at", Thu, 11 Aug 2011 18:30:34 UTC +00:00], ["featured", nil], ["song_id", 6], ["updated_at", Thu, 11 Aug 2011 18:30:34 UTC +00:00]]
   (0.1ms)  COMMIT

Notice the: ["featured", nil]

Any idea what i'm doing wrong? How can i properly set attributes on my join without accessing it directly?

thank you!

EDIT: To make my issue more clear:

  • From an instance of artist i am unable to create new featured songs through the featured_songs relationship

  • Saves appear to be setting all of the song attributes EXCEPT for (the most important one) featured

  • The featured attribute is being set to nil for some reason and this is the real issue here.

like image 468
Mario Zigliotto Avatar asked Nov 14 '22 18:11

Mario Zigliotto


1 Answers

I found the working solution after reading this:

https://github.com/rails/rails/issues/5178#issuecomment-4181551

The trick is to create a new first-order has_many association that contains the condition, and then run the has_many :through on that.

So, in your case, it would be:

class Artist < ActiveRecord::Base
  # Relationships
  has_many  :releases
  has_many  :songs, :through => :releases

  has_many  :featured_releases, :class_name => "Release", :conditions => { :featured => true }
  has_many  :featured_songs, :through => :featured_releases, :source => :song
end
like image 138
Craig Walker Avatar answered Jan 10 '23 20:01

Craig Walker