views:

26

answers:

1

What is the recommended approach for finding multiple, unique associated models for a subset of another model? As an example, for a subset of users, determine unique artist models they have favorited.

One approach is to grab the users from the database, then iterate them all quering for favorites and building a unique array, but this seems rather inefficient and slow.

class User < ActiveRecord::Base
  has_many :favorites
end

class Artist < ActiveRecord::Base
  has_many :favorites
end

class Favorite < ActiveRecord::Base
  belongs_to :user
  belongs_to :artist
end

@users = User.find_by_age(26)
# then determine unique favorited artists for this subset of users.
+1  A: 

The has_many association has a option called unique for this requirement:

class User < ActiveRecord::Base
  has_many :favorites
  has_many :artists, :through => :favorites, :unique => true
end

class Artist < ActiveRecord::Base
  has_many :favorites
  has_many :users, :through => :favorites, :unique => true
end

class Favorite < ActiveRecord::Base
  belongs_to :user
  belongs_to :artist
end

Usage:

# if you are expecting an array of users, then use find_all instead of find_
@users = User.find_all_by_age(26, :include => :artists)
@users.each do |user|
  user.artists # unique artists
end

Edit 1

I have updated the answer based on user's comment.

Solution 1- :group

Artist.all(:joins => :users, :group => :id, 
  :conditions => ["users.age = ?", 26])

Solution 2- SELECT DISTINCT

Artist.all(:joins => :users, :select => "DISTINCT artists.*", 
  :conditions => ["users.age = ?", 26]))
KandadaBoggu
This would give you an array of unique artists per user, not a unique list for all users. Am I correct? I'd like the final artist array to be unique
raidfive
I have updated the answer, take a look.
KandadaBoggu
thanks! I believe this should work perfect, going to give it a shot now.
raidfive