with tutorial rails multiple images files aws ruby-on-rails ruby file-upload carrierwave

ruby-on-rails - rails - ruby carrierwave tutorial



Cambiar el nombre de los archivos cargados con Carrierwave (6)

Aquí está la solución, cómo cambiar el nombre del archivo, si store_dir ya contiene el archivo con el nombre exacto :

if File.exists?(Rails.root.join("documents/" + "#{file.filename}")) && !path.to_s.eql?(Rails.root.join("documents/" + original_filename).to_s) @name ||= File.basename(original_filename, ''.*'') + Digest::MD5.hexdigest(File.dirname(current_path)).from(25) "#{@name}.#{file.extension}" else "#{original_filename}" end

Nota : Rails.root.join("documents/") se define como mi store_dir .

Espero que ayude a alguien.

Estoy usando Carrierwave para subir archivos, y lo tengo funcionando.

Mi problema es intentar cambiar el nombre del archivo cargado.

En el uploader.rb generado hay un método que creo que debería estar usando

def filename "something.jpg" if original_filename basename = "what"+orginal_filename if original_filename, works basename = (0...8).map{65.+(rand(25)).chr}.join if original_filename # will create a random name for each version, e.g. the orginal, the thumb, and the filename in the db, useless end

Parece que no puedo acceder a elementos como ''extensión'' o ''content_type'' en sanitized_file.rb, así que esto está un poco más allá de mi nivel de habilidad actual en este momento.

¿Alguna sugerencia o ejercicio para hacer esto, es decir, generar nombre de archivo para un archivo cargado que funciona tan bien como el predeterminado de carrierwave (no hacer nada, pero continúa con cada versión)? Parece que debería ser lo suficientemente simple, pero me he tropezado con esto.


Bueno, otro problema con su generador de nombre de archivo aleatorio es que es posible tener colisiones ¿no? Posiblemente pueda generar un nombre de archivo que ya se haya generado. Una forma de hacerlo sería generar de alguna manera un hash basado en propiedades únicas de la imagen, como la ruta del archivo. Un ejemplo, del group carrierwave:

def filename if original_filename @name ||= Digest::MD5.hexdigest(File.dirname(current_path)) "#{@name}.#{file.extension}" end end

Esto creará un hash MD5 basado en la ruta actual y luego agregará la extensión del archivo original.

Editar: La wiki de carrierwave agregó una entry con algunos métodos sobre cómo crear nombres de archivo aleatorios y únicos para todos los archivos versionados.


Del grupo de Google :

def filename @name ||= "#{secure_token}.#{file.extension}" if original_filename end private def secure_token ivar = "@#{mounted_as}_secure_token" token = model.instance_variable_get(ivar) token ||= model.instance_variable_set(ivar, ActiveSupport::SecureRandom.hex(4)) end


La otra solución se ve bien, pero la forma en que lo hice fue tener un gancho que creaba una cadena aleatoria para un nuevo nombre en la creación de la instancia, luego:

def filename "#{model.randomstring}.#{model.image.file.extension}" end

en el cargador.

Eso funcionó, poniendo la generación de nombres aleatorios como parte del modelo, y luego usando carrierwave.

Tengo curiosidad por saber qué es más rápido, más efectivo, más razonable, más sano, etc.


Para hacer que el prefijo record.id sea el nombre del archivo, puede hacer lo siguiente:

class MyUploader < CarrierWave::Uploader::Base storage :file def store_dir model.class.to_s.underscore.pluralize end def filename model.id ? "#{model.id}-#{original_filename}" : original_filename end def url "/#{store_dir}/#{model.id}-#{model.file_before_type_cast}" end end


Para tener un nombre de archivo único (no casi único), recomiendo usar la gema uuid.

en Gemfile agregar:

gem ''uuid''

en file_uploader.rb:

def filename if original_filename if model && model.read_attribute(mounted_as).present? model.read_attribute(mounted_as) else @name ||= "#{mounted_as}-#{uuid}.#{file.extension}" end end end protected def uuid UUID.state_file = false uuid = UUID.new uuid.generate end