#はじめに
前回の記事【Railsチュートリアル】プロフィール画像をアプリ内で設定できるように変更で、sample_appにおいて、プロフィール画像をアプリ内で設定できるようにしたが、本番環境でアセットパイプラインに関してのエラーが発生したため、carrierwaveを用いた方法に変更する。
また、Rialsチュートリアル第6版13章においてAWSのS3を作成済みなので、今回は本番環境のみそちらにアップロードするよう設定していく。
前提
第6版sample_appが完成している
#carrierwaveの設定
Gemfileにcarrierwaveを追加
gem 'carrierwave'
$ bundle install
アップローダーの作成し、uploadersディレクトリの中にavatar_uploader.rbが作成されているのを確認する。
$ rails g uploader Avatar
usersテーブルにavatarカラムを追加する。
ここで注意すべきなのが、カラム名をimageにしてしまうと何故かエラーが発生するのでそれ以外にする必要がある。
rails g migration add_avatar_to_users avatar:string
class AddImageToUsers < ActiveRecord::Migration[6.1]
def change
add_column :users, :avatar, :string
end
end
$ rails db:migrate
ユーザーコントローラーのuser_paramsにavatarカラムを追加
.
.
.
private
def user_params
params.require(:user).permit(:name, :email, :password,
:password_confirmation, :avatar)
end
.
.
.
ユーザーモデルにマウントを記述
class User < ApplicationRecord
.
.
.
mount_uploader :avatar, AvatarUploader
.
.
.
#ユーザー編集画面で画像変更を可能にする
初期画像default_user.jpgをapp/assets/imagesディレクトリ下に用意しておく。
├ app/
├ assets/
├ images/
└ default_user.jpg
ユーザー編集のビューを変更する。
.
.
.
<%= form_with(model: @user, local: true) do |f| %>
.
.
.
<% if @user.avatar? %>
<%= image_tag @user.avatar.url, width: "100px", height: "100px", class:"icon"%>
<% else%>
<%= image_tag "default_user.jpeg", width: "100px", height: "100px", class:"icon"%>
<% end %>
<%= f.label :avatar, "Icon change" %>
<%= f.file_field :avatar, class: 'form-control' %>
<%= f.submit "Save changes", class: "btn btn-primary" %>
<% end %>
</div>
</div>
以下のようになっていれば成功。
#画像を表示する
gravatarで表示していたビューをimage_tagに変更していく。
画像を持たないユーザーにはデフォルトの画像を表示させる。
編集するビューは以下。
- views/microposts/micropost.html.erb
- views/shared/_user_info.html.erb
- views/users/_user.html.erb
- views/users/edit.html.erb
- views/users/show_follow.html.erb
- views/users/show.html.erb
例えば
<%= link_to gravatar_for(micropost.user, size: 50), micropost.user %>
を
<% if micropost.user.avatar? %>
<%= link_to image_tag(micropost.user.avatar.url, width: "50px", height: "50px", class:"icon"),micropost.user%>
<% else%>
<%= link_to image_tag("default_user.jpeg", width: "50px", height: "50px", class:"icon"),micropost.user%>
<% end %>
というように変更する。
最後にcssを変更する。
自分は画像を丸く表示させたかったので以下のように記述。
.
.
.
.icon {
border-radius: 50%;
object-fit: cover;
float: left;
margin-right: 10px;
}
以下のようになっていれば成功。
#本番環境でAWS S3にアップロードするよう設定
現在の設定ではアップロードされた画像はpublic/uploads/user/avatarに追加されていくが、本番環境のみRialsチュートリアル第6版13章で作成したAWS S3にアップロードするように設定していく。
Gemfileにfog-awsを追加
gem 'fog-aws'
$ bundle install
avatar_uploader.rbの設定を変更
今回は画像のみ受け付けたいのでdef extension_allowlist
も記述したが、iPhoneで撮影した写真は拡張子がheicであることも多いため、jpgなどに変換する機能を検討中である。
.
.
.
if Rails.env.development?
storage :file
elsif Rails.env.test?
storage :file
else
storage :fog
end
.
.
.
def extension_allowlist
%w(jpg jpeg png)
end
end
チュートリアルにおいて、下記の環境変数をHerokuに設定済みなので、そちらを利用していく。
もしまだなら、
$ heroku config:add
で追加していく。
config/initializers配下に、carrierwave.rbを作成し、設定を記述していく。
require 'carrierwave/storage/abstract'
require 'carrierwave/storage/file'
require 'carrierwave/storage/fog'
if Rails.env.production?
CarrierWave.configure do |config|
config.fog_provider = 'fog/aws'
config.fog_directory = ENV['AWS_BUCKET']
config.fog_credentials = {
provider: 'AWS',
region: ENV['AWS_REGION'],
aws_access_key_id: ENV['AWS_ACCESS_KEY'],
aws_secret_access_key: ENV['AWS_SECRET_KEY'],
path_style: true
}
end
end
AWSを開き、Amazon S3→バケット→アクセス許可と進み、ブロックパブリックアクセス (バケット設定)を以下のように設定する。
バケットポリシーに以下のように記述
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "statement1",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::(AWSアカウントID):user/(IAMユーザー名)"
},
"Action": "*",
"Resource": "arn:aws:s3:::(バケット名)"
}
]
}