【发布时间】: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