先に解決策
ここではRailsのファイル構成を想定
- CarrierWaveのasset_hostに適当なホスト指定(ex. http://test.statics.local)
- WebMockのstub_requestでそのホストを指定
- public以下を配信する小さなRackサーバーを実装
- stub_requestのto_rackでそのRackサーバーを指定
Gemfile
gem 'webmock', group: :test
gem 'mimemagic', group: :test
test/helpers/statics_server.rb
class StaticsServer
def self.call(env)
@root = Rails.root.join('public').to_s
path = Rack::Utils.unescape(env['PATH_INFO'])
file = @root + path
if File.exists?(file)
mime = MimeMagic.by_path(file)
[ 200, {"Content-Type" => mime.type}, [mime.mediatype == 'text' ? File.read(file) : File.binread(file)] ]
else
[ 404, {'Content-Type' => 'text/plain'}, 'file not found' ]
end
end
end
test/test_helper.rb
ENV['RAILS_ENV'] ||= 'test'
require File.expand_path('../../config/environment', __FILE__)
require 'rails/test_help'
include WebMock::API
require File.expand_path('../../test/helpers/statics_server', __FILE__)
class ActiveSupport::TestCase
# Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order.
fixtures :all
# Add more helper methods to be used by all tests here...
WebMock.allow_net_connect!
stub_request(:get, /test.statics.local\/.*/).to_rack(StaticsServer)
end
config/initializers/carrierwave.rb
CarrierWave.configure do |config|
#...
config.asset_host = ENV['ASSET_HOST']
end
config/environments/test.rb
Rails.application.configure do
#...
ENV['ASSET_HOST'] = 'http://test.statics.local'
end
#問題
CarrierWaveで例えば
class User < ActiveRecord::Base
mount_uploader :avatar, AvatarUploader
end
としてると
user = User.first
user.avatar.url
のようにアクセスできるが、
デフォだとホスト名なしで"/url/to/file.png"のような文字列が返ってくる。
(storage :file
の場合)
ホスト名がないので以下のようにurlをフェッチすることができない。
require 'open-uri'
open(user.avatar.url) do |f|
#...
end
asset_hostを設定すればホスト名がつくので
CarrierWave.configure do |config|
config.asset_host = 'http://localhost:3000'
end
としてrails s
すればurlをフェッチできるけどめんどい。
なので適当なホスト名をつけたらアップロードファイルにプロキシしてくれるような機構がほしい。