【问题标题】:Exporting to CSV and Summing hours in Ruby on Rails在 Ruby on Rails 中导出为 CSV 并汇总小时数
【发布时间】:2015-06-25 15:31:21
【问题描述】:

我有一个 Rails 3.2.21 应用程序,我正在其中构建时钟功能。我目前正在编写一个应该执行以下操作的to_csv 方法:

使用列名创建标题行 遍历输入(记录)块并显示员工用户名、时钟输入、时钟输出、工作站和评论对象,最后在块的最后一行显示总小时数。

在每个用户之间,我想显示他们总小时数的总和。正如您在to_csv 方法中看到的那样,我可以通过将csv << [TimeFormatter.format_time(ce.user.clock_events.sum(&:total_hours))] 的数组铲到CSV 中来使其工作“hackish”。最终结果是它确实为我提供了每个员工的时钟事件的正确总小时数,但它在每次输入后都会重复它,因为我显然是在迭代一个块。

我想找到一种方法将其抽象到块之外,并弄清楚如何在另一个数组中铲除用户所有时钟事件的 total_hours 而没有重复条目。

以下是我的模型,如果有不清楚的地方,请告诉我。另外,如果我的问题令人困惑或没有意义,请告诉我,我很乐意澄清。

class ClockEvent < ActiveRecord::Base
  attr_accessible :clock_in, :clock_out, :user_id, :station_id, :comment
  belongs_to :user
  belongs_to :station
  scope :incomplete, -> { where(clock_out: nil) }
  scope :complete, -> { where("clock_out IS NOT NULL") }
  scope :current_week, -> {where("clock_in BETWEEN ? AND ?", Time.zone.now.beginning_of_week - 1.day, Time.zone.now.end_of_week - 1.day)}
  scope :search_between, lambda { |start_date, end_date| where("clock_in BETWEEN ? AND ?", start_date.beginning_of_day, end_date.end_of_day)}
  scope :search_by_start_date,  lambda { |start_date| where('clock_in BETWEEN ? AND ?', start_date.beginning_of_day, start_date.end_of_day) }
  scope :search_by_end_date, lambda { |end_date| where('clock_in BETWEEN ? AND ?', end_date.beginning_of_day, end_date.end_of_day) }

  def punch_in(station_id)
    self.clock_in = Time.zone.now
    self.station_id = station_id
  end

  def punch_out
    self.clock_out = Time.zone.now
  end

  def completed?
    clock_in.present? && clock_out.present?
  end

  def total_hours
    self.clock_out.to_i - self.clock_in.to_i
  end    

  def formatted_clock_in
    clock_in.try(:strftime, "%m/%d/%y-%H:%M")
  end

  def formatted_clock_out
    clock_out.try(:strftime, "%m/%d/%y-%H:%M")
  end

  def self.search(search)
    search ||= { type: "all" }

    results = scoped

    # If searching with BOTH a start and end date
    if search[:start_date].present? && search[:end_date].present?
      results = results.search_between(Date.parse(search[:start_date]), Date.parse(search[:end_date]))

      # If search with any other date parameters (including none)
    else
      results = results.search_by_start_date(Date.parse(search[:start_date])) if search[:start_date].present?
      results = results.search_by_end_date(Date.parse(search[:end_date])) if search[:end_date].present?
    end
    results
  end

  def self.to_csv(records = [], options = {})
    CSV.generate(options) do |csv|
      csv << ["Employee", "Clock-In", "Clock-Out", "Station", "Comment", "Total Shift Hours"]
      records.each do |ce|
        csv << [ce.user.try(:username), ce.formatted_clock_in, ce.formatted_clock_out, ce.station.try(:station_name), ce.comment, TimeFormatter.format_time(ce.total_hours)] 
        csv << [TimeFormatter.format_time(ce.user.clock_events.sum(&:total_hours))]      
      end
      csv << [TimeFormatter.format_time(records.sum(&:total_hours))]
    end
  end

end

【问题讨论】:

    标签: ruby ruby-on-rails-3 csv


    【解决方案1】:

    在朋友的帮助和研究 APIdocs 的帮助下,我得以重构该方法:

    def self.to_csv(records = [], options = {})
          CSV.generate(options) do |csv|
            csv << ["Employee", "Clock-In", "Clock-Out", "Station", "Comment", "Total Shift Hours"]
            # records.group_by{ |r| r.user }.each do |user, records|
              records.each do |ce|
              csv << [ce.user.try(:username), ce.formatted_clock_in, ce.formatted_clock_out, ce.station.try(:station_name), ce.comment, TimeFormatter.format_time(ce.total_hours)]
              #csv << [TimeFormatter.format_time(records.select{ |r| r.user == ce.user }.sum(&:total_hours))]
            end
           records.map(&:user).uniq.each do |user|
             csv << ["Total Hours for: #{user.username}"]
             csv << [TimeFormatter.format_time(records.select{ |r| r.user == user}.sum(&:total_hours))]
           end
    
            csv << ["Total Payroll Hours"]
            csv << [TimeFormatter.format_time(records.sum(&:total_hours))]
          end
        end
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-09-12
      • 1970-01-01
      • 1970-01-01
      • 2012-05-25
      • 1970-01-01
      • 2012-02-14
      • 2016-03-24
      • 2011-05-23
      相关资源
      最近更新 更多