Most idiomatic way to identify and modify an association directly

Suppose that we have Radio Stations which play Songs by means of a License.

John Feminella <johnf@...> writes:

Suppose that we have Radio Stations which play Songs by means of a License.

======= class Song   has_many :licenses   has_many :radio_stations, :through => :licenses end

class RadioStation   has_many :licenses   has_many :songs, :through => :licenses end

class License   belongs_to :radio_station   belongs_to :song end

Licenses are either active or not. Given a Song, we want to know which Licenses are active. If that information was on Song instead, we could just do something like:

    scope :licensed_for_radio_station, lambda { |rs| where(:licensed_stations => rs) }

But we can't, since it's on License instead. So, two questions:

    1.) Given a Song, we want to know which Licenses are active. What's the most idiomatic way to do this? Association method? Scope? etc.     2.) Given a Song and a RadioStation, what's the most idiomatic way to find the association that links them?     3.) Given a Song and a RadioStation, what's the most idiomatic way to modify the corresponding license to have :active => true?

Any thoughts are appreciated. Thanks!

~ jf

Since licenses can either be active or deactive, I assume there is a boolean field behind it, in which case a scope would be handy:

class License   belongs_to :radio_station   belongs_to :song   scope :activated, where => :active = true end

This should allow you to perform the following:

song = Song.first licences_for_song = song.licences.active

or even

licensed_stations = song.licences.activated.radio_stations

If you already have the radio station, finding of it is listed should be easy:

licensed_stations.include? radio_station

The last issue is a little more complex, but I think something along the lines of:

License.where(:song => song).where(:radio_station => radio_station).activate!

Then create a method to respond (I am assuming the combined keys are unique):

class License   belongs_to :radio_station   belongs_to :song   scope :activated, where => :active = true

  def activate!     update_attribute :active, true   end end

Andrew Skegg <andrewskegg@...> writes:

Sorry,this is slightly wrong:

song = Song.first licences_for_song = song.licences.active

It should be:

licences_for_song = song.licences.activated

And this can be optimised if you do not need all the licenses:

licensed_stations.include? radio_station

To:

license = song.licences.activated.where(:radio_station = radio_station)