ruby-on-railsrubyroo-gem

Rails Roo gem .xlsx output contains the object not the output of method


I am using the Roo gem to output a spreadsheet from a Rails app. One of my columns is a hash (Postgres DB). I would like to format the cell contents into something more readable. I am using a method to return a human readable cell.

The column data looks like this:

Inspection.first.results
=> {"soiled"=>"oil on back",
"assigned_to"=>"Warehouse@firedatasolutions.com",
"contaminated"=>"blood on left cuff",
"inspection_date"=>"01/01/2017",
"physical_damage_seam_integrity"=>"",
"physical_damage_thermal_damage"=>"",
"physical_damage_reflective_trim"=>"",
"physical_damage_rips_tears_cuts"=>"small tear on right sleeve",
"correct_assembly_size_compatibility_of_shell_liner_and_drd"=>"",
"physical_damage_damaged_or_missing_hardware_or_closure_systems"=>""}

In my Inspections model I defined the following method:

def print_results
  self.results.each do |k,v|
    puts "#{k.titleize}:#{v.humanize}\r\n"
  end
end

So in the console I get this:

Inspection.first.print_results

Soiled:Oil on back
Assigned To:Warehouse
Contaminated:Blood on left cuff
Inspection Date:01/01/2017
Physical Damage Seam Integrity:
Physical Damage Thermal Damage:
Physical Damage Reflective Trim:
Physical Damage Rips Tears Cuts:Small tear on right sleeve
Correct Assembly Size Compatibility Of Shell Liner And Drd:
Physical Damage Damaged Or Missing Hardware Or Closure Systems:
=> {"soiled"=>"oil on back",
 "assigned_to"=>"Warehouse",
 "contaminated"=>"blood on left cuff",
 "inspection_date"=>"01/01/2017",
 "physical_damage_seam_integrity"=>"",
 "physical_damage_thermal_damage"=>"",
 "physical_damage_reflective_trim"=>"",
 "physical_damage_rips_tears_cuts"=>"small tear on right sleeve",
 "correct_assembly_size_compatibility_of_shell_liner_and_drd"=>"",
 "physical_damage_damaged_or_missing_hardware_or_closure_systems"=>""}

But when I put this in the index.xlsx.axlsx file

wb = xlsx_package.workbook
wb.add_worksheet(name: "Inspections") do |sheet|
  sheet.add_row ['Serial Number', 'Category', 'Inspection Type', 'Date', 
   'Pass/Fail', 'Assigned To', 'Inspected By', 'Inspection Details']
  @inspections.each do |inspection|
    sheet.add_row [inspection.ppe.serial, inspection.ppe.category, 
    inspection.advanced? ? 'Advanced' : 'Routine',
    inspection.results['inspection_date'], 
    inspection.passed? ? 'Pass' : 'Fail', 
    inspection.ppe.user.last_first_name,
    inspection.user.last_first_name, 
    inspection.print_results]
  end
end

The output in the spreadsheet is the original hash, not the results of the print statement.

{"soiled"=>"oil on back", 
"assigned_to"=>"Warehouse", 
"contaminated"=>"blood on left cuff", "inspection_date"=>"01/01/2017", 
"physical_damage_seam_integrity"=>"", 
"physical_damage_thermal_damage"=>"", 
"physical_damage_reflective_trim"=>"", 
"physical_damage_rips_tears_cuts"=>"small tear on right sleeve", 
"correct_assembly_size_compatibility_of_shell_liner_and_drd"=>"", 
"physical_damage_damaged_or_missing_hardware_or_closure_systems"=>""}

Is it possible to get the output of the method into the cell rather than the hash object?


Solution

  • The problem is that your print_results method prints out what you want to stdout (that is, the console), but still returns the original hash. The return value of the method is all that matters to Roo.

    What you want to do is rewrite print_results to return the formatted string:

    def print_results
      self.results.map do |k,v|
        "#{k.titleize}:#{v.humanize}\r\n"
      end.join
    end
    

    This will return a string (note the use of .join to combine the array of strings returned by .map) that you can throw into Roo and get your desired output.