Shrineは@janko-mによって書かれた新しいFileUploaderです。
先日からGithubのトレンドに入っており気になっていましたが、日本語の情報が見つからないので試しに使ってみました。
同じようなgemには下記のようなものがあります。
しかし、これらのgemはコードが複雑すぎたり、拡張が難しかったりする問題点があります。
Shrineの特徴は、既存のgemのような複雑なコードベースから脱却して、pluginの設計を取り入れたシンプルなコードベースです。
その上、非同期処理や並列処理などの非常に便利な機能もサポートしています。
新しいgemを作ろうとされたモチベーションは@janko-mの書かれた記事が参考になります。Introducing Shrine – A file upload toolkit
require 'shrine'
require 'shrine/storage/file_system'
Shrine.storages = {
cache: Shrine::Storage::FileSystem.new(Dir.tmpdir),
store: Shrine::Storage::FileSystem.new('public')
}
class AttachmentUploader < Shrine
# 必要な機能だけpluginとして読み込む
plugin :store_dimensions
end
class Attachment
attr_accessor :file_data
include AttachmentUploader[:file]
end
attachment = Attachment.new
attachment.file = File.open('path/to/file.jpg')
puts attachment.file_url #=> '/var/folders/l3/2qbqhkws59gd7ts5g98zslxr0000gn/T/f19ea7f8b06fa1361d999eb596d9a0c8089400fdfe7c4bf30992009cba1a.jpg'
puts attachment.file.height #=> 275
puts attachment.file.width #=> 275
良い点
- 設定が簡単で導入が楽(s3なども扱える)
- 最低限必要な機能がデフォルトでサポートされている
- 非同期処理や並列処理がサポートされており、先鋭的
- 必要なpluginだけ選択して読み込むため処理が速い
- 機能が細かくpluginに分けられており、シンプルなコードベースを保っている
- CarrierWaveはバグを踏んだ時にデバッグが非常に大変だけれど、Shrineはpluginを絞ることができるのでデバッグが容易
悪い点
- 全体的に設計やコードの書き方がイマイチ。
- クラスにuploaderを組み込む際に、データを保存するための変数名(DBのカラム名)が固定されている(
#{name}_data
) - pluginと違って、Shrineクラスはなぜか分割されておらずやや複雑になっている
- 個人的にはvalidationと、
Shrine.[]
のメソッド名と実装が気に入らない。
ちなみに、やや不思議であるがActiveRecordをサポートしているのに、なぜかドキュメントにきちっとした使い方が記述されていない。
# 下記の実装で動くはず。
# migration
create_table :images do |t|
t.text :file_data
end
# uploader
class ImageUploader < Shrine
plugin :activerecord
end
# model
class Image < ActiveSupport::Base
include ImageUploader[:file]
end
なかなか面白そうですが、まだお仕事で使えるクオリティではないのでもう暫く様子を見てみます。