web-dev-qa-db-ja.com

Carrierwaveを使用してアップロードされたファイルの名前を変更する

Carrierwaveを使用してファイルをアップロードしていますが、正常に機能しています。

アップロードしたファイルの名前を変更しようとしています。

生成されたuploader.rbには、私が使用すべきメソッドがあると思います

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

Sanitized_file.rbの「extension」や「content_type」などのアイテムにアクセスできないようです。これは、現在の私のスキルレベルを少し超えています。

これを行うための提案または演習、つまり、carrierwaveのデフォルトと同様に機能するアップロードされたファイルのファイル名を生成します(何もしないが、各バージョンに引き継がれます)?それは十分に単純であるように思えますが、私はこれにつまずきました。

31
waving

さて、ランダムファイル名ジェネレータのもう1つの問題は、衝突が発生する可能性があることですよね。すでに生成されているファイル名を生成する可能性があります。これを実行する1つの方法は、ファイルパスなど、画像の一意のプロパティに基づいてハッシュを生成することです。例、carrierwave group から:

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

これにより、現在のパスに基づいてMD5ハッシュが作成され、元のファイルの拡張子が追加されます。

編集:carrierwave wikiは entry をいくつかの方法で追加しました。

34
Jack Chu

実際には一意のファイル名(ほとんど一意ではない)にするには、uuid gemを使用することをお勧めします。

gemfileに追加:

gem 'uuid'

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
5
ramigg

Google Group から:

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
1
bouchard

他の解決策は良さそうですが、それを行う方法は、インスタンスの作成時に新しい名前のランダムな文字列を作成するフックを持つことでした:

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

アップローダーで。

これは機能し、ランダムな名前の生成をモデルの一部として配置し、それをcarrierwaveに使用させました。

私はより速く、より効果的で、合理的で、音などが気になります。

1
blueblank

Record.idプレフィックスをファイル名にするだけで、次のことができます。

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
1
T.N.T.

_store_dir_に既に正確な名前のファイルが含まれている場合に、ファイルの名前を変更する方法と解決策を次に示します。

_  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
_

Rails.root.join("documents/")はmy _store_dir_として定義されています。

それが誰かを助けることを願っています。

0
mArtinko5MB