31

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」などのアイテムにアクセスできないようです。これは、現在の私のスキル レベルを少し超えています。

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

4

6 に答える 6

34

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

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

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

編集: Carrierwave wiki に、バージョン管理されたすべてのファイルに対してランダムで一意のファイル名を作成する方法に関するいくつかの方法が記載されたエントリが追加されました。

于 2011-05-03T04:44:32.210 に答える
5

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

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
于 2012-05-22T15:04:40.507 に答える
1

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

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

アップローダーで。

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

私は、より速く、より効果的で、合理的で、音などがどれであるか興味があります。

于 2011-05-04T13:44:28.227 に答える
1

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
于 2011-08-28T17:15:11.537 に答える
1

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
于 2011-07-19T12:19:15.860 に答える
0

正確な名前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

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

于 2012-11-27T14:25:51.307 に答える