开发者

Ruby and MySQL Db query group limit

开发者 https://www.devze.com 2023-03-22 05:34 出处:网络
I\'m trying to return for a given user (current_user) activities created through the week (last 7 days) and group by day with sum of time spent on each.

I'm trying to return for a given user (current_user) activities created through the week (last 7 days) and group by day with sum of time spent on each.

current_user has_many projects currents_user has_many activities through :projects

For each of the last 7 days I want to sum up time spent on activities (each activity has time field to store time spent) where project is internal (project.internal is boolean)

In other words here is what I need. Todays is Wednesday.

Today:

  • Total activities time for internal project
  • Total activities time for not internal project

Yesterday ...

2.days.ago ... and so on for the last 7 days

What goes in the model, controller and views?

Ideally it would need to work with MySQL开发者_运维百科 and SQLite. Thank you in advance.


Methods like this are best defined in your models and exercised in your views. The controller only really serves to set things up so that the view can do its work.

The advantage to defining these in the model is you can write unit tests for them which are usually easier to set up than functional or integration tests. Your methods are also easy to test from the console command line.

For a lot of things you can simply exercise the sum method on your relationships. It may look something like this:

user.activities.sum(:time_spent)

You can apply scopes to the activities relationship to better target the result.

Update

To group together by different parameters, you can always express this as a SQL join and extract the computed values. The query would look something like this:

SELECT users.id, projects.internal, SUM(activities.time) AS total_time, activities.on_date
  FROM users
  LEFT JOIN projects ON projects.user_id=users.id
  LEFT JOIN activities ON activities.project_id=projects.id
  GROUP BY users.id, projects.internal, activities.on_date

Once you've got that set up properly, adjusting the column names as required, you can wrap it in a call that will make it easy to extract values:

class User < ActiveRecord::Base
  def self.time_spent_on_projects(user_id = nil)
    query = "..." # Query from above

    # Allow scoping to a particular user by adding a WHERE clause
    query = self.sanitize_sql([ "#{query} WHERE users.id=?", user_id ])

    self.connection.select_all(query)
  end

  def time_spent_on_projects
    self.class.time_spent_on_projects(self.id)
  end
end

This will return all values as String or nil, so you may need to convert to numbers as required.

0

精彩评论

暂无评论...
验证码 换一张
取 消