es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Rails 5 ¿Cómo cargar csv generado (carrierwave)?

En mi aplicación quiero subir archivos .csv a la nube usando carrierwave, pero antes quiero probar el uploader local, pero no sé cómo subir la cadena csv generada en la aplicación. En mi aplicación se ve así:

/uploaders/file_uploader.rb

class FileUploader < CarrierWave::Uploader::Base
  # Choose what kind of storage to use for this uploader:
  storage :file

<p># define some uploader specific configurations in the initializer
  # to override the global configuration</p>

<p>def store_dir
    "uploads/#{model.id}"
  end
end

/models/rooms.rb

class Rooms < ApplicationRecord
  mount_uploader :file, FileUploader</p>

<p>end

/services/generate_csv

require 'csv'</p>

<p>class GenerateCsv</p>

<p>def initialize(room)
    @room = room
  end

  def build
   csv_string = gen_csv
   @room.file = StringIO.new(csv_string)
   @room.save!
  end

  def gen_csv
    CSV.generate do |csv|
      csv << headers

      users.each do |user|
        csv << GenerateRow.gen(room: @room)
      end
    end
  end

end

Y no funciona. Después de room.save! la columna file es nil. ¿Existe alguna opción para subir el csv generado y asociarlo a la columna de la base de datos (después de todo, solo necesito la URL para descargar)? ¿Debo crear un archivo csv en lugar de una cadena csv? ¿Puede ayudarme con esto?

@EDIT

Solución

/services/generate_csv
...
def build
csv_string = gen_csv
@room.file = StringIO.new(csv_string)
@room.save!
end
...

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Para subir una cadena CSV generada usando CarrierWave, puede crear un objeto StringIO a partir de la cadena y asignarlo al cargador:

    def build
      csv_string = gen_csv
      @room.file = StringIO.new(csv_string)
      @room.save!
    end
    

    Esto creará un objeto en memoria similar a un archivo a partir de la cadena CSV y lo asignará al cargador, que se encargará de subirlo al almacenamiento en la nube. Asegúrese de requerir stringio en la parte superior del archivo:

    require 'stringio'
    

    Como alternativa, podría escribir la cadena CSV en un archivo temporal en disco y asignar el camino del archivo al cargador:

    def build
      csv_string = gen_csv
      tmp_file = Tempfile.new(['datos', '.csv'])
      tmp_file.write(csv_string)
      tmp_file.rewind
      @room.file = tmp_file
      @room.save!
      tmp_file.close!
    end
    

    Esto escribirá la cadena CSV en un archivo temporal con un nombre único, asignará el camino del archivo al cargador y eliminará el archivo después de guardar. Sin embargo, usar StringIO debería ser suficiente para su propósito.

Comments are closed.