问题
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.
回答1:
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
回答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.
来源:https://stackoverflow.com/questions/11270467/union-of-2-active-record-relation-object-in-rails-3