paperclip で保存した attachment の path を変更する
最近の仕事でプライベートなファイルがpublicなディレクトリにおいていることがわかったので、ファイルの置き場所を変更しました。(ちなみにプライベートなWEBサイトでbasic認証はかかっている)
paperclip で下記のようにモデルの定義をすると、デフォルトのパスに従ったディレクトリに保存します。
class Invoice < ActiveRecord::Base
has_attached_file :pdf
end
しかし、デフォルトの値だとnginx が配信できるディレクトリに保存してしまいますので、下記のようにpathとurl を上書きしなければなりません。
class Invoice < ActiveRecord::Base
has_attached_file :pdf,
url: '/:class/:id/:attachment',
path: ':rails_root/non-public/system/:class/:attachment/:id_partition/:style/:filename'
end
すでに保存されているファイルを新しいパスに移動するには、attachmentを再代入してsaveします。
paperclip のwikiにあったコードを参考にすると下記のように書くと移行できます。
def old_path
':rails_root/public/system/:class/:attachment/:id_partition/:style/:filename'
end
def migrate_old_pdf
logger = Logger.new('./migrate.log')
Invoice.find_each do |invoice|
unless invoice.pdf?
logger.warn "#{invoice.id} にPDFを持っていないためskipします"
next
end
pdf_path = Paperclip::Interpolations.interpolate(old_path, invoice.pdf, 'original')
unless File.exists?(pdf_path)
logger.warn "#{invoice.id} にPDFを持っていますがFSにファイルが存在していないのでskipします"
next
end
File.open(pdf_path) do |file|
invoice.pdf = file
invoice.save!
end
logger.info "#{invoice.id} のPDFを移行しました"
end
end
def delete_old_pdf
require 'FileUtils'
Invoice.find_each do |invoice|
pdf_path = Paperclip::Interpolations.interpolate(old_path, invoice.pdf, 'original')
FileUtils.rm(pdf_path)
end
end
上位のディレクトリだけが変わるだけなので mv コマンドでも十分っぽい...。
参考
-
category:
- rails