最近、ファイルアップロード用のgemであるShrine
を使用する機会があったんですが、Uploader別にアップロード先を設定する方法が全然見つからず、だいぶハマってしまったので、やり方をφ(..)メモメモ
github.com
とりあえず公式のQuick startを見てみる
Shrine.storage
に各Uploaderが共通で使用するストレージを情報を設定できる。
config/initializers/shrine.rb
require "shrine"
require "shrine/storage/file_system"
Shrine.storages = {
cache: Shrine::Storage::FileSystem.new("public", prefix: "uploads/cache"),
store: Shrine::Storage::FileSystem.new("public", prefix: "uploads/store"),
}
Shrine.plugin :sequel
Shrine.plugin :cached_attachment_data
Shrine.plugin :restore_cached_data
Shrine.plugin :rack_file
共通のアップロード先にアップロードするだけだったら、簡単で使いやすい😃
アップロード先を個別に設定する
Quick startを見てみるとShrine.strages
にアップロード先の情報を設定されているため、この値を変更する必要があるっぽい。
でも単純にShrine.strageを変更すると、画像アップロード処理全体に影響してしまう...😭
各クラスにShrine.strages
がなぜ反映されているか?
Shrine.starages
はグローバル変数みたいな感じで定義されていて、それを参照しているのかと思ったけど、
どうやらサブクラスのクラスインスタンス変数としてdup
でコピーされた値が反映されているっぽい😳
https://github.com/shrinerb/shrine/blob/master/lib/shrine.rb#L101
class Shrine
@storages = {}
module Base
subclass.instance_variable_set(:@storages, storages.dup)
各Uploaderクラスに個別でアップロードパスを設定するには?
サブクラスのクラスインスタンス変数として設定されているということは、こんな感じでUploader別に設定出来るのでは?? 👀
class HogeImageUploader < Shrine
@storages = {
cache: Shrine::Storage::FileSystem.new("public", prefix: "uploads/hoge/cache"),
store: Shrine::Storage::FileSystem.new("public", prefix: "uploads/hoge/store"),
}
image_url
も変わってる、できたっぽい🙌
[1] pry(main)> HogeImage.first.image_url
=> "/uploads/store/hoge/hogehoge.png"
[2] pry(main)> FugaImage.first.image_url
=> "/uploads/store/fugafuga.png"
S3のバケットを使う場合でも同じように個別に設定してあげればOKみたいです😃
class HogeImageUploader < Shrine
s3_options = {
bucket: "my-bucket",
access_key_id: "abc",
secret_access_key: "xyz",
region: "my-region",
}
@storages = {
cache: Shrine::Storage::S3.new(prefix: "cache", **s3_options),
store: Shrine::Storage::S3.new(**s3_options),
}
2018/06/03追記
default_strage
pluginをつかっても下記のような感じで出来るみたいですφ(..)
require "shrine"
require "shrine/storage/file_system"
Shrine.storages = {
cache: Shrine::Storage::FileSystem.new("public", prefix: "uploads/cache"),
store: Shrine::Storage::FileSystem.new("public", prefix: "uploads/store"),
special_cache: Shrine::Storage::FileSystem.new("public", prefix: "uploads/cache"),
special_store: Shrine::Storage::FileSystem.new("public", prefix: "uploads/store"),
}
Shrine.plugin :sequel
Shrine.plugin :cached_attachment_data
Shrine.plugin :restore_cached_data
Shrine.plugin :rack_file
class HogeImageUploader < Shrine
plugin :default_storage, cache: :special_cache, store: :special_store
end
Shrine::Plugins::DefaultStorage