相較於傳統的 multipart/form-data
表單上傳,在 API 中將文件以 Base64 形式編碼後置於 JSON 中會是更為妥貼的實現方式。
Carrierwave 是一個知名的文件上傳 GEM。下文將主要闡述在 Rails4 與 Carrierwave 中如何實現一個不依賴於具體數據庫的獨立上傳 API。
# app/models/media.rb
class Media
include ActiveModel::Model
attr_accessor :path, :type, :original_filename, :content_type
attr_writer :file
validates :path, presence: true
validates :original_filename, presence: true
validates :content_type, presence: true
validates :type, inclusion: %w(logo image video)
def file
data = StringIO.new(Base64.decode64(@file))
data.class.class_eval { attr_accessor :original_filename, :content_type } # 確保與 Carrierwave 所預期的格式保持一致
data.original_filename = original_filename
data.content_type = content_type
data # 返回 data
end
def upload!
uploader = Object.const_get("#{type.classify}Uploader").new # 允許按需上傳到不同的 Uploader
uploader.store! file
self.path = uploader.url
end
end
為保證更好的閱讀體驗,全文請見我的博客: https://hacker.design/design-json-upload-api-base-by-carrierwave/