UPDATE: use http://github.com/grosser/random_records for random
This morning i wanted to:
- Select records
- Scoped
- Random
- Unique
- Joined through 2 tables
The scope
Person.filmmakers
named_scope :filmmakers, :joins=>{:team_memberships=>:movie}, :conditions=>{'movies.status'=>'online'}, :group=>'people.id'
So we want people that participated in a movie, and add group so that there are no duplicates.
Counting
Person.filmmakers.count
Does not work! Count discards group, since cont(:group=>something) would result in [[a,number_of_records_with_a],…]
So lets add a counting that works as expected, by returning the sum of all count results(sum of the distinct values).
scope_from_above do def count super(:group=>'people.id').size end end
Random
Person.filmakers.random(3)
Normally random looks like this.
#UPDATE: use http://github.com/grosser/random_records for random class ActiveRecord::Base def self.random(num=1,options={}) return [] if num.zero? num_records = count find(:all, {:offset => [rand(num_records),num_records-num].min, :limit=>num}.merge(options)) end end
It does not use the scope count that we defined, but the regular count, so we have to pass in count separately.
And it returns records where the id is set to Movie.count or the last movie id, very strange.
Final scope and random
named_scope :filmmakers, :joins=>{:team_memberships=>:movie}, :conditions=>{'movies.status'=>'online'}, :group=>'people.id' do def count super(:group=>'people.id').size end def random(num=1,options={}) #select people.* or id will always be Movie.count WTF super(num,options.merge(:count=>count,:select=>'people.*')) end end #UPDATE: use http://github.com/grosser/random_records for random class ActiveRecord::Base def self.random(num=1,options={}) return [] if num.zero? num_records = count find(:all, {:offset => [rand(num_records),num_records-num].min, :limit=>num}.merge(options)) end end