How to omit empty rows using last_row in Roo Rails

若如初见. 提交于 2019-12-24 17:03:53

问题


I have a spreadsheet of members designed as below:

My aim is to upload some columns and exclude others. In this case, I wish to upload only the name, age and email and exclude the others. I have been able to achieve this using the slice method as shown below:

def load_imported_members
    spreadsheet = open_spreadsheet
    spreadsheet.default_sheet = 'Worksheet'
    header = spreadsheet.row(1)
    (2..spreadsheet.last_row).map do |i|
      row = Hash[[header, spreadsheet.row(i)].transpose]
      member = Member.find_by_id(row["id"]) || Member.new
      member.attributes = row.to_hash.slice("id", "name", "age", "email")
      member
    end
  end

The problem is that last_row considers all the rows upto the last one (13), and since there are validations on the form, there are errors due to missing data as a result of the empty rows (which shouldn’t be considered). Is there a way I can upload only specific columns as I have done, yet limit to only the rows that have data?


回答1:


You might want to chain the map call off of a reject filter like this example

You may just need to change the map line to this (assuming the missing rows all look like those above): (2..spreadsheet.last_row).reject{|i| spreadsheet.row(i)[0] }.map do |i|

This is assuming the blank rows return as nil and that blank rows will always have all four desired fields blank as shown in the image. The reject call tests to see if spreadsheet.row(i)[0], the id column, is nil, if so the item is rejected from the list output given to map




回答2:


Thanks for this question. I have learned some things from this question.

I have shortlisted your answer [note: use 'ROO' gem]

def load_imported_members(member)
  spreadsheet = open_spreadsheet(member)
  spreadsheet.each do |records|
  record = @spreadsheet ? Hash[[@header, @spreadsheet.row(records)].transpose] : Hash[records] # transpose for xlsx records and 
  attributes =  {id: record['id'], name: record['name'], email: record['email'], age: record['age']}
  member_object = Member.new(attributes)
  if member_object.valid?
    if Member.find(attributes[:id])
      Member.find(attributes[:id]).update(attributes)
    else
      member_object.save
    end
  end
 end
end

You can parse your uploaded file using Roo gem.

def self.open_spreadsheet(member)
case File.extname(member.file.original_filename)
when ".csv" then
  Roo::CSV.new(member.file.expiring_url, csv_options: {headers: true, skip_blanks: true, header_converters: ->(header) { header.strip }, converters: ->(data) { data ? data.strip : nil }})
when ".xlsx", ".xls" then
  @spreadsheet = Roo::Spreadsheet.open(member.file.expiring_url)
  @header = @spreadsheet.row(1)
  (2..@spreadsheet.last_row)
 end
end

Here I have used s3 uploaded url i.e expiring_url. Hope This will helpful. I have not tested. sorry, for small errors.

If you have used validations for name, email, and age. This will surely help u..



来源:https://stackoverflow.com/questions/58517282/how-to-omit-empty-rows-using-last-row-in-roo-rails

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!