重构这个ruby数据库/续集gem查找

时间:2013-06-20 06:18:51

标签: ruby refactoring

我知道这段代码不是最优的,有关如何改进它的想法吗?

job_and_cost_code_found = false
  timberline_db['SELECT Job, Cost_Code FROM [JCM_MASTER__COST_CODE] WHERE [Job] = ? AND [Cost_Code] = ?', job, clean_cost_code].each do |row|
    job_and_cost_code_found = true
  end

if job_and_cost_code_found == false then 
  info = linenum + "," + id + ",,Employees default job and cost code do not exist in timberline. job:#{job} cost code:#{clean_cost_code}"
  add_to_exception_output_file(info)
end

2 个答案:

答案 0 :(得分:2)

你在这里打破了许多简单的规则。

请勿选择不使用的内容。

您选择了多个列,然后完全忽略结果数据。你可能想要的是一个计数:

SELECT COUNT(*) AS cost_code_count FROM [JCM_MASTER__COST_CODE] WHERE [Job] = ? AND [Cost_Code] = ?'

然后你会得到一个row,其中包含零或非零值。将其保存为变量,如:

job_and_cost_codes_found = timberline_db[...][0]['cost_code_count']

请勿与false进行比较,除非您需要区分nil

在Ruby中,只有两件事评估为 false nilfalse。大多数时候你不会担心差异。在极少数情况下,您可能希望为集true设置不同的逻辑,设置false或不设置(nil),然后才会进行特定测试。

但是,请注意0不是假值,因此您需要与之进行比较。

考虑到之前的优化,您的if可以是:

if job_and_cost_codes_found == 0
  # ...
end

请勿使用then或其他冗余语法位

大多数Ruby样式指南都会像then一样抛弃无用的语法,就像他们建议避免for一样,而是使用更灵活的Enumerable类。

操纵数据,而不是字符串

你最终会在那里组装某种类似CSV的行。理想情况下,您将使用built-in CSV library来执行正确的编码,而像这样的库需要数据,而不是他们必须解析的字符串。

更接近这一点是:

line = [
  linenum,
  id,
  nil,
  "Employees default job and cost code do not exist in timberline. job:#{job} cost code:#{clean_cost_code}"
].join(',')

add_to_exception_output_file(line)

您可能会使用适用于此处的CSV编码方法替换join(',')。当你可以提前将所有数据编译成数组数组时,库会更有效,所以如果这是最终目标,我建议你这样做。

例如:

lines = [ ]

# ...

if (...)
  # Append an array to the lines to write to the CSV file.
  lines << [ ... ]
end

将数据保存在标准结构(如Array,Hash或自定义对象)中,直到您准备将其提交到最终的格式化或编码形式。这样,如果您需要执行过滤等操作,则可以对其执行其他操作。

答案 1 :(得分:0)

当我不确定它应该做什么时,很难重构这一点,但假设你想在没有与作业相匹配的条目时记录错误。代码对,这是我提出的:

def fetch_by_job_and_cost_code(job, cost_code)
  timberline_db['SELECT Job, Cost_Code FROM [JCM_MASTER__COST_CODE] WHERE [Job] = ? AND [Cost_Code] = ?', job, cost_code]
end

if fetch_by_job_and_cost_code(job, clean_cost_code).none?
  add_to_exception_output_file "#{linenum},#{id},,Employees default job and cost code do not exist in timberline. job:#{job} cost code:#{clean_cost_code}"
end