views:

71

answers:

1

Hi all,

I have a models User

class User < ActiveRecord::Base  
  has_many :ratings  
  has_many :rated_films, :through => :ratings, :source => :film  
end  

and Films

class Film < ActiveRecord::Base  
  has_many :users, :through => :ratings  
end  

I am looking to find all Films that have not been rated by the specified user, smth like

class Film < ActiveRecord::Base  
  has_many :users, :through => :ratings  
  named_scope :not_rated_by_user, lambda { |user|  
    {:joins => :users, :conditions => ['? NOT IN users', user]}  
  }  
end  

Film.not_rated_by_user(User.first)  

I am not that familiar with SQL so am not quite sure if this could be achieved in a named scope.

Many thanks

Yuriy

A: 

I suppose you have a ratings table, which is your join table. Right? So you need something like:

class User < ActiveRecord::Base  
   has_many :ratings
   has_many :rated_films, :through => :ratings, :source => :film  
end

class Film < ActiveRecord::Base  
   has_many :ratings
   has_many :users, :through => :ratings

   named_scope :not_rated_by_user, lambda { |user_id| {
      :include => :ratings,
      :conditions => ['? NOT IN (ratings.user_id)', user_id]
   }}
end

class Rating < ActiveRecord::Base
   belongs_to :film
   belongs_to :user
end

And you can use

Film.not_rated_by_user(User.first.id)

Please let me know if it helped. I haven't tested!

j.
it executes without error but don't produce expected result
Yuriy
What's the result?
j.
>> Film.not_rated_by_user(User.first.id)=> []
Yuriy
And you're sure there's a `film` this `user` didn't rate, right?
j.
yes, `User.first.rated_films.count => 100` , `Film.count => 4359`
Yuriy
Right. I've edited the named scope... I hope it works now!
j.
unfortunately no, even when I fixed a typo in lamda `user => user_id`
Yuriy
I don't know then :/
j.
Thanks for trying
Yuriy