Rails добавление строки в csv, в которой есть только заголовки и нет данных, удаляет заголовки

#ruby-on-rails #csv #ruby-on-rails-3

#ruby-on-rails #csv #ruby-on-rails-3

Вопрос:

Я читаю файл CSV из CDN и добавляю в него данные, а затем записываю его обратно в CDN по этой причине я не могу использовать append file.

Я также переупорядочиваю файл, поэтому я должен превратить его обратно в CSV ::Table

Этот код представляет собой уменьшенную версию того, что у меня есть, но проблема все еще копируется.

 class SomeForm::Form
  class << self

    def add
      data = CSV.parse(open(csv_file_url).read, headers: true)
      data << ['david', 'smith'] # this will be dynamic
      # data = data.sort_by { |row| [row['Firstname'], row['Lastname']] }
      write_csv_file(CSV::Table.new(data).to_csv)
    end


    def csv_file_url
      #somecode to get the file_url
    end

    def write_csv_file(data)
      #somecode to write the file to the cdn
    end
  end
end

  

Файл CSV

 Firstname,Lastname
  

Поэтому, если я запускаю SomeForm ::Form.add с файлом csv, как указано выше, он выводит (удаляя заголовки)

 ,
David,smith
  

Однако, если в файле CSV есть хотя бы одна запись, например

 Firstname,Lastname
Steve,Cougan
  

и запустите код, который добавляет новую запись, как ожидалось

 Firstname,Lastname
Steve,Cougan
david,smith
  

Я хотел бы заставить это работать с csv с данными и csv только с заголовками.

Кроме того, это для проекта rails3, хотя вышеуказанное также можно воспроизвести в rails 5

Заранее спасибо

Ответ №1:

Я упростил сценарий, но я не могу воспроизвести вашу проблему.

 data = CSV.parse("Firstname,Lastname", headers: true)
data << ['david', 'smith'] # this will be dynamic
data = data.sort_by { |row| [row['Firstname'], row['Lastname']] }
puts CSV::Table.new(data).to_csv

# Firstname,Lastname
# david,smith
  

Однако, если у вас все еще возникает проблема, я полагаю, что это может быть сортировка. CSV::Table Класс является перечислимым, но выполняет итерации только по строкам CSV без заголовков (за исключением col режима), так что это означает, что ваша сортировка может просто возвращать массив массивов без заголовка. Когда вы теперь инициализируете новый CSV::Table , он по умолчанию будет использовать первую строку в качестве заголовков. Пожалуйста, обратите внимание, что вы также можете получить доступ к заголовкам и установить их следующим образом.

 data = CSV.parse("Firstname,Lastname", headers: true)
headers = data.headers

data << ['david', 'smith'] # this will be dynamic
data = data.sort_by { |row| [row['Firstname'], row['Lastname']] }

puts CSV::Table.new(data, headers: headers).to_csv
  

Вот ссылки на реализацию:

Ответ №2:

Я провел некоторое исследование, следуя ответу Крисиан.

И думаю, что это может быть проблемой https://github.com/ruby/csv/issues/75