更新时间:2023-12-01 22:02:34
印象派宝石代码/impressionist/blob/master/lib/impressionist/is_impressionable.rb#L15-L20rel =nofollow> association ,并在 impressionist_coun您可以创建自己的范围,如下所示:
范围:order_by_starting_at, - > (start_date){
impressions_table = Impression.quoted_table_name
query = if start_date.present?
#{impressions_table} .created_at> ='#{start_date}'AND
else
'
end
query + = #{impressions_table} .created_at< ='#{Time.now}'
order(%Q {
COALESCE((
SELECT
COUNT(# {impressions_table} .impressionable_id)
FROM
#{impressions_table}
JOIN
#{Post.quoted_table_name} AS popular_posts
ON
popular_posts.id =# {impressions_table} .impressionable_id
AND
#{impressions_table} .impressionable_id ='#{self.to_s}'
WHERE
#{query}
),0) DESC
})
}
范围:view_counts_for_first, - > (number){
order_by_starting_at.limit(number)
}
现在你可以:
Post.order_by_starting_at(1.week.ago).limit(10)
Post.order_by_starting_at.limit (10)
编辑:
然而,结果证明这个效果更好 -
Post.joins(:impressions).where(impressions.created_at
I have Post model and It's impressionable
using Impressionist gem
I want to show top 10 most visited Post in last month.
Here is the way I came up with:
Post.all.sort_by{|post| post.view_count_last_month}.first 10
and view_count_last_month
method is in Post
model:
def view_count_last_week
impressionist_count(:start_date => 1.week.ago)
end
But I think it's not good for performance because It loads all the Posts and then sort them by view_count_last_month
method.
What is the best way to do that?
Thanks
By looking at the Impressionist gem code for association and in impressionist_count, you can actually create your own scope like this:
scope :order_by_starting_at, -> (start_date){
impressions_table = Impression.quoted_table_name
query = if start_date.present?
"#{impressions_table}.created_at >= '#{start_date}' AND "
else
''
end
query += "#{impressions_table}.created_at <= '#{Time.now}'"
order(%Q{
COALESCE((
SELECT
COUNT(#{impressions_table}.impressionable_id)
FROM
#{impressions_table}
JOIN
#{Post.quoted_table_name} AS popular_posts
ON
popular_posts.id = #{impressions_table}.impressionable_id
AND
#{impressions_table}.impressionable_id = '#{self.to_s}'
WHERE
#{query}
), 0) DESC
})
}
scope :view_counts_for_first,-> (number){
order_by_starting_at.limit(number)
}
now you can:
Post.order_by_starting_at(1.week.ago).limit(10)
Post.order_by_starting_at.limit(10)
EDIT:
However, it turned out that this worked even better -
Post.joins(:impressions).where("impressions.created_at<='#{Time.now}' and impressions.created_at >= '#{start_time}'").group("impressions.impressionable_id").order("count(impressions.id) DESC")