In a Rails 4.1.2 app with MySQL I'm doing the following:
scope :popular, -> {
select("images.*, SUM(likes_count + comments_count + reposts_count) as score").
where("DATE(created_at) > DATE(?)", 4.weeks.ago).
order('score DESC')
}
to get a recent set of "popular" images. The problem is that if there are no images that match this query, I get an ActiveRecord::Relation
with all nil values, eg..
#<ActiveRecord::Relation [#<Image id: nil, user_id: nil, image_uid: nil, image_name: nil>]>
This is causing problems as the collection is not empty. How would I get that scope to return 'nil' if no results, or just reject if the object is empty or something?
UPDATE
Image.popular.select {|i| i.id.present? }
kinda solves the problem, but to me this seems more like a workaround than a solution...
You could make sure you're not returning anything with a nil
value for id
. Perhaps something like:
scope :popular, -> {
select("images.*, SUM(likes_count + comments_count + reposts_count) as score").
where("DATE(created_at) > DATE(?) AND id IS NOT NULL", 4.weeks.ago).
order('score DESC')
}
EDIT
An alternative approach would be to simplify your query by caching the score
attribute on the model. Generate a migration and add your attribute to your model. Then, use a before_save
callback:
before_save :cache_score
def cache_score
self.score = likes_count + comments_count + reposts_count
end
Then you could make your query simpler:
scope :popular, -> { where("created_at > ?", 4.weeks.ago).order('score DESC') }
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.