Gem source code Demo source code
Author: Bogdan Gusiev

User Grid (basic) Time Entry Grid (advanced) Document Grid (Mongoid)

Time Entries Grid


Developer Project Report hours
Ashlynn Wilderman voluptatem quaerat architecto 82.0
Itzel Littel minus quaerat quo 36.0
Sheldon Harvey voluptatem quaerat architecto 62.0
Fausto Larkin molestiae laudantium quo 52.0
Isabel Okuneva consequuntur nihil quo 75.0
Albina Morissette molestiae laudantium quo 65.0
Elaina Schiller voluptatem quaerat architecto 68.0
Reta Boyer molestiae laudantium quo 79.0
Benedict Muller voluptatem quaerat architecto 47.0
Triston Lynch molestiae laudantium quo 46.0
Carmel Huel minus quaerat quo 55.0
Zackery Dibbert voluptatem quaerat architecto 70.0
Danika Bins voluptatem quaerat architecto 66.0
Christa Smith minus quaerat quo 63.0
Maximillian Ryan molestiae laudantium quo 52.0
Hortense Leffler voluptatem quaerat architecto 45.0
Clyde Bruen voluptatem quaerat architecto 51.0
Tod Heller consequuntur nihil quo 46.0
Constance Ward molestiae laudantium quo 65.0
Rosanna Schowalter voluptatem quaerat architecto 71.0
Earline Hahn molestiae laudantium quo 89.0
Earline Hahn minus quaerat quo 25.0
Anahi Rice consequuntur nihil quo 93.0
Maximillian Ryan minus quaerat quo 67.0
Ambrose Marvin minus quaerat quo 74.0

Grid:

class TimeEntriesGrid

  include Datagrid

  #
  # Scope
  #

  scope do
    User.select(
      "users.name, projects.name as project_name, accounts.name as account_name, sum(time_entries.hours) as report_hours"
    ).joins(:time_entries => {:project => :account}).group("projects.name", "users.name", "accounts.name").order("users.name")

  end


  #
  # Filters
  #

  filter(:project_id, :enum,
    :select => lambda {Project.all.map {|p| [p.name, p.id]}},
    :multiple => true,
    :include_blank => false
  ) do |value|
    self.where(:time_entries => {:project_id => value})
  end


  filter(:year, :enum,
         :select => lambda { TimeEntry.all.any? ? (TimeEntry.minimum(:date).year..TimeEntry.maximum(:date).year) : []},
    :include_blank => false,
    :default => lambda {Date.today.year}
  ) do |value|
    self.where(["extract(year from time_entries.date) = ?", value.to_i])
  end

  filter(:month, :enum,
         :select => Date::MONTHNAMES[1..12].enum_for(:each_with_index).collect {|name, index| [name, index + 1]},
         :include_blank => false,
         :default => lambda {Date.today.month}
        ) do |value|

    self.where(["extract(month from time_entries.date) = ?", value.to_i])
  end


  #
  # Columns
  #

  column(:user_name, :header => "Developer", :order => "users.name") do
    self.name
  end
  column(:project_name, :header => "Project", :order => "projects.name")
  column(
    :account_name,
    :header => "Company",
    :order => "accounts.name",
  ) do |model|
    format(model.account_name) do
      render :partial => "time_entries/company", :locals => {:model => model}
    end
  end

  column(:report_hours, order: "sum(time_entries.hours)")

end

Controller:

class TimeEntriesController < ApplicationController

  def index
    @time_entries_grid = TimeEntriesGrid.new(params[:time_entries_grid]) do |scope|
      scope.page(params[:page])
    end
  end
end

View:


<h3>Time Entries Grid</h3>


<div class="left">
  <%= datagrid_form_for @time_entries_grid, url: time_entries_path %>
  <br/>

  <%= datagrid_table(@time_entries_grid) %>
  <%= paginate @time_entries_grid.assets %>

</div>

<div class="right">
  <%= render :partial => "shared/source", :object => @time_entries_grid %>
</div>