Toriというgemを書いた。
ToriはPaperclipやCarrierwaveなどと同じくファイルのアップローダ。
ファイルアップローダは機能が豊富だったりする反面、ハマることが多かったり結局コードを読むことになるけど、機能豊富がゆえコード量に気が滅入ったりする。
そこで新しいファイルアップローダを考えた。
というか既にあるものからできるだけ機能を削った。
目指した特徴は「なにもしない」こと。
極限までシンプルなものを目指した。
画像処理をしない
昨日書いた通り、画像処理をアプリケーションサーバでやるのはイマイチだ。
だったらファイルアップローダに画像処理機能はいらない。
アップロード時だろうがアクセス時だろうが一切何もしない。
imagemagickにも依存しない。
DBに専用カラムを用意しない
PaperclipやCarrierwaveではファイル名を決めるためにDBに専用のカラムを用意しなければならない。
新規作成するアプリには問題ないが、既存のシステムにファイルアップロード機能を付けたい場合には導入をためらうキッカケになる。
そこで、ToriではDBに専用のカラムを追加する必要をなくしている。
ファイル名の決定はユーザ側が任意にロジックを決定できるようにした。
ファイル名の遅延決定
ファイル名の決定ロジックを設定で変更できる。
デフォルトはこう。
Tori.config.filename_callback = ->(model) do Digest::SHA1.hexdigest "#{model.class.name}/#{model.id}" end
このブロックがファイル名を取得したいときに呼ばれる。 modelはToriを使いたいclass(Railsで言えばActiveRecord::Base)のインスタンスを渡すようになっていて、遅延評価で決定できる。つまりはDBのidからファイル名を決定できる。
ファイル名の決定ロジックを後から設定で変更できるので、コードを公開しなければファイル名を特定するは非常に困難になる。
このへんの考えはというかほとんどのコードはRefileからパクって参考にしている。
Hashingしたくなければ変えられるし、MD5を使いたければ設定すればいい。 MurmurHashやSiphashアルゴリズムを使いたい? 僕がすでに書いている。(宣伝)
callbackはcall
メソッドを持っていればなんでもいい。
ファイルの保存場所
ファイルの保存にはまだマシンローカルにしか対応していないけど、S3にも標準対応を目指している。 この保存場所も設定で変更可能になっているし、なんならプラグイン的にclassを書ける。
設定は
Tori.config.backend = GodStorage.new
保存時は
Tori.config.backend.copy(from_filename, to_filename)
削除時は
Tori.config.backend.delete(filename)
と呼べばいい。
ちなみにRailsではGemfileで
gem 'tori', require: 'tori/rails'
としておけば自動的にafter_save
とafter_destory
にフックして
自動でストレージに保存したり削除する仕掛けになっている。
コード量
小さいのでハマる確率は低いと思われるが、開発者フィルターがふんだんにかかっている。
全部で140行ぐらいなので読める範囲だと思う。
詳しくはksss/toriで。
リスク
僕の気分次第で仕様が変わる。
なにもしないので何も紹介できることがない。
まとめ
"(\( ⁰⊖⁰)/)"