こちらのTipsでは最小限の記述でHeroku環境で画像アップロードを実装します。
HerokuサーバはGit管理下にないファイルはキャッシュされませんので別途画像を保存しておくストレージが必要となります。
今回はHerokuの兄弟サイトであるCloudinaryを使って画像をアップロードすることにします。
それぞれの役割を確認しておいてください。
参考サイト
以下環境で動作確認しています。
ruby: 2.6.6 Rails: 6.0.3.1
動作確認日: 2020/05/28
任意の名前でプロジェクトを作成しディレクトリの移動をおこなってください。
※このTipsではプロジェクト名をImageUploadとしています。
こちらでは開発環境のデータベースはMySQLを使うものとしていますが、任意のお好きなもので構いません。
$ rails new ImageUpload -d=mysql $ cd ImageUpload
Gitリポジトリも登録しておきましょう。
$ git init $ git add . $ git status $ git commit -m "app init"
今回使うGemを全てインストールしておきます。
Gemfileの一番下に追加(※任意の場所でも良いです)
Herokuの推奨データベースはPostgreSQLなのでこちらを使います。
gem pgをHeroku(prodution)でインストールされるようにしておきます。
gem 'cloudinary' , '1.11.1' gem 'carrierwave', '~> 1.3.1' gem 'pg', group: :production
Gem cloudinaryはHerokuとストレージであるCloudiinaryを連携するためのGemです。
Gem carriewaveが画像アップロードを行うライブラリになります。
Herokuで推奨されているPostgreSQLというデータベースサーバを使うためのライブラリ「pg」を本番環境でインストールされるようにしておきます。
追記しましたらインストールを実行してください。
$ bundle install
Herokuアプリを作成しましょう。heroku infoコマンドで表示URLも確認しておいてください。
※Herokuにログインしていない方はemailとpasswordを聞かれますのでHerokuアカウントのメールとログインパスワードを入力してください。
$ heroku create アプリ名 $ heroku info
次にHerokuとCloudinaryを連携するためのアドオンを追加します。(Herokuサイトのダッシュボードからも追加できますがコマンドで実施します。)
※アドオンとはHerokuの追加機能のことです。
$ heroku addons:add cloudinary:starter
アップローダーを作成します。このアップローダーファイルはCarrieawaveを使って画像をアップロードするための設定ファイルです。
複数モデルがありそれぞれ別の設定を行いたい場合は複数アップローダーを作成してください。今回のアップローダー名はUserとします。
$ rails g uploader User create app/uploaders/user_uploader.rb
app/uploaders/user_uploader.rbファイルが作成されました。
作成したアップローダー「app/uploaders/user_uploader.rb」を編集します。
class UserUploader < CarrierWave::Uploader::Base
include Cloudinary::CarrierWave
end
画像をアップロードし、名前と一緒に画像を表示するようにします。
Userモデルにnameカラムとアップロードした画像のURLを入れるimageカラムを持たせましょう。
DB作成とマイグレーションも行ってください。
$ rails g model User name image $ rails db:create $ rails db:migrate
作成したuserモデルに作成したアップローダーを設置します。app/models/user.rbファイルを以下のように編集してください。
class User < ApplicationRecord mount_uploader :image, UserUploader end
画像ファイルのURLを格納するカラム名はimage、作成したアップローダーはUserUploaderなので上記のように設置します。
mount_uploader :対象カラム名, アップローダ―クラス名
usersコントローラを作成します。
TOPページはusers#indexで表示し、こちらに入力フォームを設置しますので以下のように設定しています。
$ rails g controller users index
usersコントローラを編集します。app/controllers/users_controller.rbを以下のように編集してください。
class UsersController < ApplicationController def index @user = User.new #form用インスタンス @users = User.all #ユーザー一覧表示用 end def create @user = User.new(user_params) @user.save redirect_to root_url end private def user_params params.require(:user).permit(:name, :image) end end
rails s
画像をアップロードするViewを作成していきましょう。
今回はTOPページで画像をアップし、users#createアクションでDBに保存を行い、User一覧としてTOPページで表示させます。
config/routes.rbを以下のように編集してください。
Rails.application.routes.draw do root 'users#index' resources :users, only: [:create] end
TopぺージとUser作成のルートになります。
app/views/users/index.html.erbファイルを以下のように編集してください。
<%= form_with model: @user, local: :true do |f| %> <%= f.label :name %> <%= f.text_field :name %> <%= f.file_field :image %> <%= f.submit '登録' %> <% end %> <h2>User一覧</h2> <% @users.each do |user| %> <%= user.name %> <%= image_tag(user.image.to_s) %> <%# カラム名がimageの場合はto_sが必要 %> <% end %>
※今回のようにカラム名が「image」の場合は表示時にto_sメソッドで文字列にする必要があります。
image以外のカラム名の場合は「to_sメソッド」は不要になります。
※こちらの設定は開発・テスト環境から画像をアップするテスト用に必要です。
Heokuの公式サイトに行き、アプリケーションのDashboardのOverviewタブにある Cloudinaryをクリックするとこのアプリに紐づいたCloudinaryのサイトに遷移します。
※ここでCloudinaryのアイコンやリンクが表示されていない方はアドオンの追加ができていません。また、アドオンの追加にはクレジットカードの登録が必要になります。
※Cloudinaryのサイトではアンケート(質問)が表示されますが詳細は割愛します。スキップしても大丈夫です。
CloudinaryのDashboardのAccountDetailsの右側にダウンロードリンクがありますのでYMLをクリックしてダウンロードしてください。
ダウンロードしたファイルをconfigディレクトリに配置します。config/cloudinary.yml
※このままGithubなどでソースコードを公開しないでください。
cloudinary.ymlにはapi_keyが記載されていますのでこのまま公開しますと悪用されてしまいます。
公開する際はgitignoreに追加するなど各自対応してください。
Herokuで使うPostgreSQL用の設定を記述します。database.ymlファイルのProductionの部分を変更します。
config/database.yml
※YAMLファイルのインデントは半角スペース2つです。注意してください。
production:
adapter: postgresql
pool: 5
encoding: unicode
database: ImageUpload_production
username: ImageUpload
password: <%= ENV['IMAGEUPLOAD_DATABASE_PASSWORD'] %>>
前述しましたがこのまま公開すると非常に危険です。API_keyは環境変数に登録しましょう。ファイルに記載してあるcloud_name、api_key、api_secretの値は後で使いますので控えておいてください。
config/cloudinary.ymlファイルを以下のように編集してください。
--- development: cloud_name: <%= ENV['CLOUDINARY_CLOUD_NAME'] %> api_key: <%= ENV["CLOUDINARY_API_KEY"] %> api_secret: <%= ENV["CLOUDINARY_API_SECRET"] %> enhance_image_tag: true static_image_support: false test: cloud_name: <%= ENV['CLOUDINARY_CLOUD_NAME'] %> api_key: <%= ENV["CLOUDINARY_API_KEY"] %> api_secret: <%= ENV["CLOUDINARY_API_SECRET"] %> enhance_image_tag: true static_image_support: false
以下コマンドでサーバを立ち上げ動作確認してください。
※Dotenv-Railsなど任意の方法で環境変数に登録している方はrails sで起動して大丈夫です。
$ CLOUDINARY_CLOUD_NAME=取得したcloud_name CLOUDINARY_API_KEY=取得したAPI__key CLOUDINARY_API_SECRET=取得したapi_secret rails s
名前とファイルを選択し、登録後画像が表示されればOKです。
Cloudinaryのサイトに行きますと画像がアップロードされているのがわかると思います。
KeyError in UsersController#create
key not found: :ciphers
以下画像のようにエラーとなる場合はrest-client というgemのバージョンを2.0.2に指定する必要があります。
Gemfileの一番下に以下行を追加してください。
gem 'rest-client', '2.0.2'
その後bundle updateを行います。
$ bundle update
サーバを再起動して動作確認を行ってください。
ローカルで動作確認ができましたらデプロイしましょう。
※エラーが出るものをデプロイするのは危険です。
必ずローカルでしっかりと動作確認を行ってください。
$ git add . $ git status $ git commit -m "Deploy to Heroku" $ git push heroku master $ heroku run rails db:migrate
herokuで動作確認をし、画像がCloudinaryにアップロードされていれば完成です!