担当しているプロジェクトではファイルのアップロードにCarrierWaveを使っているのですが、ファイル名の取得ってどうやるんだろう?と思ってCarrierWaveをマウントしたカラムを見たところ
model_with_file.file_column
=> #<FileUploader:0x007ff886cdc388
@file=
#<CarrierWave::SanitizedFile:0x007ff886cd7c98
@content_type=nil,
@file=
"/path/to/filename.pdf",
@original_filename=nil>,
@model=
#<ModelWithFile:0x007ff886cdc748
id: 39,
file: "filename.pdf",
created_at: Fri, 26 Jan 2018 19:12:17 JST +09:00,
updated_at: Fri, 26 Jan 2018 19:12:17 JST +09:00>,
@mounted_as=:file_column,
@storage=
#<CarrierWave::Storage::File:0x007ff886cdc2e8
@uploader=#<FileUploader:0x007ff886cdc388 ...>>,
@versions={}>
よく分からないけど@file=の中の@file=にファイルパスらしきものが見えるので
model_with_file.file_column.file
=> #<CarrierWave::SanitizedFile:0x007ff87dea58d0
@content_type=nil,
@file=
"/path/to/filename.pdf",
@original_filename=nil>
model_with_file.file_column.file.file
=> "/Users/iwatsuki.rei/Documents/donuts/roumu-server/public/uploads/uploaded_file/file/39/
File.basename(model_with_file.file_column.file.file)
=> "filename.pdf"
なんとかファイル名が取得できましたが、かなり冗長で気持ち悪いです。またアップロード先にローカルを指定している場合これでも取得できるのですが、S3の場合オブジェクトの構成が違うのかうまく取得できませんでしたので他の方法を模索します。
filenameメソッドを使えばFile.basenameを使う必要がありません。
File.basename(model_with_file.file_column.file.file.filename)
=> "filename.pdf"
file_column.pathでパスが取れるのでそのbasenameを取る方法もあります。
File.basename(model_with_file.file_column.path)
=> "filename.pdf"
model_with_file.file_columnでは上記のようなオブジェクトしか取れませんでしたが、file_columnにハッシュでアクセスするとファイル名を取得できます。
model_with_file[:file_column]
=> "filename.pdf"
これが一番シンプルそうです。