Как пропустить пустые строки, используя last_row в Roo Rails - PullRequest
0 голосов
/ 23 октября 2019

У меня есть таблица members, оформленная следующим образом: enter image description here

Моя цель - загрузить некоторые столбцы и исключить другие. В этом случае я хочу загрузить только name, age и email и исключить другие. Я смог добиться этого, используя метод slice, как показано ниже:

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

Проблема в том, что last_row рассматривает все строки до последней (13), и поскольку существуют проверкив форме есть ошибки из-за отсутствия данных в результате пустых строк (которые не должны учитываться). Есть ли способ, которым я могу загрузить только определенные столбцы, как я сделал, но ограничить только те строки, которые имеют данные?

Ответы [ 2 ]

0 голосов
/ 27 октября 2019

Возможно, вы захотите связать вызов map с фильтром reject, как этот пример

Возможно, вам просто нужно изменить строку map на это (при условиивсе пропущенные строки выглядят так, как указано выше): (2..spreadsheet.last_row).reject{|i| spreadsheet.row(i)[0] }.map do |i|

Это предполагает, что пустые строки возвращаются как ноль, и что пустые строки всегда будут иметь все четыре требуемых поля пустыми, как показано на рисунке. reject вызывает тесты, чтобы определить, равен ли spreadsheet.row(i)[0], столбец id, нулю, если это так, элемент отклоняется из вывода списка, заданного для map

0 голосов
/ 23 октября 2019

Спасибо за этот вопрос. Из этого вопроса я кое-что узнал.

Я внес в ваш ответ короткий список [примечание: используйте гем 'ROO']

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

Вы можете проанализировать загруженный файл, используя Roo драгоценный камень.

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

Здесь я использовал загруженный URL-адрес s3, т.е. expiring_url. Надеюсь это будет полезно. Я не проверял. извините, за небольшие ошибки.

Если вы использовали проверки для имени, электронной почты и возраста. Это, безусловно, поможет вам ..

...