前回に続いて今回もRailsで素振り
今回やりたいこと
Railsで画像URLを指定してダウンロードしたものをS3にアップロードする!!
例えば次のような画像
https://pbs.twimg.com/profile_images/896275871941574656/wAcSCGy4_400x400.jpg
候補
今回はアップローダーを使って実現を試みる
対象は次の2つ
Carrierwave
まずはcarrierwaveから
Gemfileに次の2つのgemを追加します
gem 'carrierwave' gem 'fog-aws'
次にモデルを作成します
$ bundle exec rails g model CarrierwaveImage image:string
carrierwaveのUploaderを作成します
これはgeneratorが付いているので次のように指定します
$ bundle exec rails g uploader Image
中身はこんな感じで設定します
今回は最低限の設定だけしているので細かい設定はGithubのREADMEを見てください
class ImageUploader < CarrierWave::Uploader::Base storage :fog def store_dir "test/carrier_wave" end end
次にcarrierwaveのinitializerを追加します
config/initializers/carrierwave.rb
CarrierWave.configure do |config| config.fog_provider = 'fog/aws' config.fog_credentials = { provider: 'AWS', aws_access_key_id: ENV['AWS_ACCESS_KEY'], aws_secret_access_key: ENV['AWS_SECRET_ACCESS_KEY'], region: 'ap-northeast-1' } config.fog_directory = 'test_bucket' # S3のバケット名 config.cache_storage = :fog end
最後にさきほど作成したUploaderをモデルの指定したカラムにマウントします
class CarrierwaveImage < ApplicationRecord mount_uploader :image, ImageUploader end
実行
carrierwaveはモデルにremote_[マウントしたカラム名]_url=
というメソッドがはえるのでそこにダウンロードしたい画像URLを指定してsaveするとアップロード処理が実行される
> c = CarrierwaveImage.new > c.remote_image_url = "https://pbs.twimg.com/profile_images/896275871941574656/wAcSCGy4_400x400.jpg" > c.save!
Paperclip
次はpaperclip
Gemfileには次のように追加します
gem 'paperclip' gem 'aws-sdk'
paperclipようのモデルを追加します
$ bundle exec rails g model PaperclipImage image:attachment
attachementはpaperclipで定義されているもので、migrateすると次のカラムがテーブルに生成されます
次にenvironmentにpaperclip用の設定を追加します
Rails.application.configure do ~~~ config.paperclip_defaults = { storage: :s3, bucket: 'test-bucket', s3_region: 'ap-northeast-1', s3_host_name: 's3-ap-northeast-1.amazonaws.com', s3_credentials: { access_key_id: ENV['AWS_ACCESS_KEY'], secret_access_key: ENV['AWS_SECRET_ACCESS_KEY'] } } end
paperclip用のinitializerを作成します
config/initializers/paperclip.rb
Paperclip::UriAdapter.register
最後はモデルにpaperclipの設定を追加します
class PaperclipImage < ApplicationRecord has_attached_file :image, path: "test/paperclip/:filename" validates_attachment_content_type :image, content_type: /\Aimage\/.*\Z/ end
実行
> pi = PaperclipImage.new > pi.image = URI.parse("https://pbs.twimg.com/profile_images/896275871941574656/wAcSCGy4_400x400.jpg") > pi.save!
最後に
今回はcarrierwaveとpaperclipを使って画像URLを指定してS3にアップロードを行いました。
個人的にはUploaderクラスとして分けるcarrierwaveが好きです