0

I have a content model represented by class: content. Now users can rate content, review content or do both. I want to find all the content that a user have either rated, reviewed or rated and reviewed. The reviews table has a many-to-one association with the content table (meaning a content can be reviewed many times). A similar relationship exists between the ratings table and the content table.

I'm thinking I should do separate queries to find all rated content by a user, then all reviewed content by a user, then do a union. But I can't find out how to do a union that returns an active record relation. I need a relation because I want to paginate the results.

Thank you.

berto77
  • 885
  • 3
  • 12
  • 29

2 Answers2

2

Ok, so first let's set up your models. From your explanation I'm thinking you'll want something like this:

class Content < ActiveRecord::Base
  has_many :reviews
  has_many :reviewing_users, :through => :reviews, :class_name => "User"

  has_many :ratings
  has_many :rating_users, :through => :ratings, :class_name => "User"
end

class User < ActiveRecord::Base
  has_many :reviews
  has_many :reviewed_contents, :through => :reviews, :class_name => "Content"

  has_many :ratings
  has_many :rated_contents, :through => :ratings, :class_name => "Content"
end

class Review < ActiveRecord::Base
  belongs_to :content
  belongs_to :user
end

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

And then for a given user you can find all the content that they've reviewed and/or rated with:

( user.reviewed_contents + user.rated_contents ).uniq
smathy
  • 26,283
  • 5
  • 48
  • 68
  • 1
    Sorry for taking so long to get back. But this worked perfectly. Thank you so much. – berto77 Aug 10 '12 at 01:31
  • Thanks to [Robertibiris](http://stackoverflow.com/users/2653957/robertibiris) for pointing out my typo – smathy Sep 11 '13 at 00:14
2

(user.reviewed_contents + user.rated_contents).uniq returns an array, not a relation, so beware. You can test this by attempting to call a class method on @posts (other than paginate).

You can still paginate though. just use @posts.paginate, as the will_paginate gem adds a paginate method to the array class.

fancyPants
  • 50,732
  • 33
  • 89
  • 96