Shrine::Error: must call Shrine::Attacher#url with the name of the version の解消

こんにちは!kossyです!




今回はファイルアップロードを可能にするGem「Shrine」で発生するエラーの解消について、
ブログに残してみたいと思います。




環境
Ruby 2.6.6
Rails 6.0.3
MacOS catalina
shrine 3.3.0




small, medium, largeのいずれかを指定する必要があった。

私のプロジェクトのShrineの設定は下記です。

# config/initializers/shrine.rb

require "shrine"
require "shrine/storage/file_system"
require 'shrine/storage/s3'

if Rails.env.production?
  s3_options = {
    access_key_id:     Rails.application.credentials.s3[:ACCESS_KEY_ID],
    secret_access_key: Rails.application.credentials.s3[:SECRET_ACCESS_KEY],
    region:            Rails.application.credentials.s3[:REGION],
    bucket:            Rails.application.credentials.s3[:BUCKET]
  }

  Shrine.storages = {
    cache: Shrine::Storage::S3.new(prefix: 'cache', **s3_options),
    store: Shrine::Storage::S3.new(prefix: 'store', **s3_options)
  }
else
  Shrine.storages = {
      cache: Shrine::Storage::FileSystem.new("public", prefix: "uploads/cache"),
      store: Shrine::Storage::FileSystem.new("public", prefix: "uploads/store")
  }
end

# 使用するプラグインの宣言
Shrine.plugin :activerecord
Shrine.plugin :cached_attachment_data
# app/uploaders/file_uploader.rb

require "image_processing/mini_magick"

class FileUploader < Shrine
  plugin :processing # allows hooking into promoting
  plugin :versions   # enable Shrine to handle a hash of files
  plugin :delete_raw # delete processed files after uploading
  plugin :validation_helpers

  process(:store) do |io, context|
    versions = { original: io } # retain original

    io.download do |original|
      pipeline = ImageProcessing::MiniMagick.source(original)

      versions[:large]  = pipeline.resize_to_limit!(800, 800)
      versions[:medium] = pipeline.resize_to_limit!(500, 500)
      versions[:small]  = pipeline.resize_to_limit!(300, 300)
    end

    versions # return the hash of processed files
  end

  Attacher.validate do
    validate_max_size 5 * 1024 * 1024, message: '5MBを超えるファイルはアップロードできません。'
    validate_mime_type_inclusion %w(image/jpeg image/png application/pdf)
  end
end
# app/models/release_note_files.rb

class ReleaseNoteFile < ApplicationRecord
  # include modules, gems
  include FileUploader::Attachment(:file)

  # Association
  belongs_to :release_note
end

この状態で、file_urlをReleaseNoteFileインスタンスに呼び出すと、

$ ReleaseNoteFile.last.file_url
Shrine::Error: must call Shrine::Attacher#url with the name of the version

タイトルに記載したエラーが発生しました。

この場合、file_urlの引数にsmallかmediumかlargeを渡せばOKです。

$ ReleaseNoteFile.last.file_url(:small)
=> "/uploads/store/c628d7499afe0a7b57b1a8d2c2a00ff2.png"

$ ReleaseNoteFile.last.file_url(:medium)
=> "/uploads/store/151d7b5445b2dc480ea2b2faecb2dc28.png"

$ ReleaseNoteFile.last.file_url(:large)
=> "/uploads/store/338b8d8ff961827891036af049075a38.png"

これでエラーの解消ができました。(凡ミスですね、、、ドキュメントをちゃんと読みましょう。)



大いに参考にさせていただいたサイト

この場を借りて御礼を申し上げます。

Shrine::Error (must call Shrine::Attacher#url with the name of the version) · Issue #225 · shrinerb/shrine · GitHub