CarrierWaveとActive Storageでのファイルアップロードの説明を書きます。
この記事はCarrierWaveになります。
前提
AWSアカウント作成済み
IAMユーザのアクセスキーを取得済み
S3のバケット作成済み
環境
ruby 2.5.1
rails 5.2.2
githubでソースを公開しています。
手順
gemを追加
Gemfile
gem "figaro", "~> 1.1.1"
gem 'carrierwave'
gem 'fog'
gem "mini_magick"
figraro: 環境変数を設定するgem
carrierwave: ファイルアップロードのgem
fog: S3にアップロードする為に必要なgem
mini_magick: 画像をリサイズする為に必要なgem
$ bundle install --path vendor/bundler
アップローダーの作成
$ bundle exec rails g uploader Image
画像のリサイズをする為にMiniMagickをincludeしています。
S3にアップロードする為にstorageは:fogを指定しています。
image_uploader.rb
class ImageUploader < CarrierWave::Uploader::Base
include CarrierWave::MiniMagick
# envで分けたい時、developmentはfile、それ以外はfogを使う
# storage if Rails.env.development? ? :file : :fog
storage :fog
def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
process resize_to_fit: [150, 150]
def extension_whitelist
%w(jpg jpeg gif png)
end
end
モデルの作成
$ bundle exec rails g model picture
マイグレーションファイルが作成されます、imageカラムを追加します。
20190106050728_create_pictures.rb
class CreatePictures < ActiveRecord::Migration[5.2]
def change
create_table :pictures do |t|
t.string :image
t.timestamps
end
end
end
マイグレーションの実行
$ bundle exec rake db:migrate
pictureモデルにアップローダーを紐付ける
app/models/picture.rb
class Picture < ApplicationRecord
mount_uploader :image, ImageUploader
end
carrierwaveの設定
ここでaccess_keyやsecret_access_key,backet名は
application.ymlに設定しています(figraroのgem)
application.ymlにはaccess_keyなどが記載されていますので
.gitignoreに追記をします。
.gitignore
# Ignore application configuration
/config/application.yml
config/application.yml
AWS_ACCESS_KEY_ID: "○○○○"
AWS_SECRET_ACCESS_KEY: "○○○○"
AWS_BUCKET: "○○○○"
DATABASE_USERNAME: "root"
DATABASE_PASSWORD: ""
config/initializers/carrierwave.rb
CarrierWave.configure do |config|
config.fog_credentials = {
provider: 'AWS',
aws_access_key_id: ENV["AWS_ACCESS_KEY_ID"],
aws_secret_access_key: ENV["AWS_SECRET_ACCESS_KEY"],
region: 'ap-northeast-1'
}
config.fog_directory = ENV["AWS_BUCKET"]
config.cache_storage = :fog
end
コントローラーやViewの作成
$ bundle exec rails g scaffold_controller pictures
コントローラーはpermitにimageを追加します。
app/controllers/pictures_controller.rb
class PicturesController < ApplicationController
before_action :set_picture, only: [:show, :edit, :update]
# GET /pictures
def index
@pictures = Picture.all
end
# GET /pictures/1
def show
end
# GET /pictures/new
def new
@picture = Picture.new
end
# GET /pictures/1/edit
def edit
end
# POST /pictures
def create
@picture = Picture.new(picture_params)
respond_to do |format|
if @picture.save
format.html { redirect_to @picture, notice: 'Picture was successfully created.' }
else
format.html { render :new }
end
end
end
# PATCH/PUT /pictures/1
def update
respond_to do |format|
if @picture.update(picture_params)
format.html { redirect_to @picture, notice: 'Picture was successfully updated.' }
else
format.html { render :edit }
end
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_picture
@picture = Picture.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def picture_params
params.fetch(:picture, {}).permit(:image)
end
end
アップロード
app/views/pictures/_form.html.erb
<%= form.file_field :image %>
画像表示
app/views/pictures/index.html.erb
<%= image_tag picture.image.to_s %>