我正在为我的Rails应用程序制作一个非常基本的分析功能。我想提供统计信息,告诉用户有多少访问者查看了他们的个人资料,然后根据每个访问者的特定角色(我在我的应用中使用'rolify')将其分解。
在Users控制器的show动作中,我这样做
@profileviews = Profileview.where(:user_id => @user.id)
@profileviewsbysomerole = Profileview.where({:user_id => @user.id, :viewer_role => 'someRole'})
@profileviewsbysomeotherrole = Profileview.where({:user_id => @user.id, :viewer_role => 'someOtherRole'})
然后在show动作中,我会做
Your profile has been viewed <%= @profileviews.size %> times.
Your profile has been viewed by users with a particular role <%= @profileviewsbysomerole.size %> times.
Your profile has been viewed by users with some other role <%= @profileviewsbysomeotherrole.size %> times.
有没有办法在不进行三次单独查询的情况下完成我想要做的事情,或者这是获得这些统计数据的最佳方式(在不降低性能方面)。
答案 0 :(得分:1)
在性能方面,我认为没关系。另一种选择是查询所有对象然后在内存中过滤,但我不认为这是一个好主意。让数据库做它最擅长的事情是最好的。
我想到的一件事 - 您可以使用单个查询和group_by以避免进行第二次和第三次通话,但如果您希望获得相关内容,则相关一些汇总数据。
在编码风格方面,您可以为不同的查询定义范围,并在视图中使用它们,但这可能是一种过度杀伤。
答案 1 :(得分:1)
如果您发现自己一起使用这些东西,将它们捆绑在一起可能会很好:
# in user model
def profile_view_hash(*roles)
views = { 'all' => Profileview.where(:user_id => id).all }
roles.each do |role|
views.merge!({
role => Profileview.where(:user_id => id, :viewer_role => role).all
})
end
views
end
这应该允许你像这样使用它:
# in controller
@profile_views = @user.profile_view_hash('someRole','someOtherRole')
# in view
<%= @profile_views['all'] %>
<%= @profile_views['someRole'] %>
<%= @profile_views['someOtherRole'] %>
顺便说一句,在您的示例中,您只显示.size的输出。如果这就是您所需要的,那么您应该使用count
而不是all
答案 2 :(得分:1)
我会将它们全部留在控制器之外,然后像这样制作视图:
Your profile has been viewed <%= @user.profileviews.size %> times.
Your profile has been viewed by users with a particular role <%= @user.profileviews.select { |profile_view| profile_view.viewer_role == 'someRole' }.size %> times.
Your profile has been viewed by users with some other role <%= @user.profileviews.select { |profile_view| profile_view.viewer_role == 'someOtherRole' }.size %> times.
你可以通过将这个逻辑移到Profileview
来更进一步,可能就像:
def views_for_role( role )
select { |profile_view| profile_view.viewer_role == role }.size
end
并将其委托给User
,也许就像:
delegate :views_for_role, :to => :profileview
哪会让你的观点看起来像这样:
Your profile has been viewed <%= @user.profileviews.size %> times.
Your profile has been viewed by users with a particular role <%= @user.views_for_role 'someRole' %> times.
Your profile has been viewed by users with some other role <%= @user.views_for_role 'someOtherRole' %> times.