【Rails】音声投稿機能 ~Cloudinary, CarrierWave


はじめに

この記事では音声ファイルの投稿機能を実装します。

Cloudinary(外部ストレージ)を使います。
フリープランで月1GBまで利用できます。

前提

Tweetモデルにて、テキストでの投稿機能は一通りできている

まず、、、

Cloudinaryにアカウントを登録してください!
メルアドにて本登録も忘れずに!

上記のアカウント取得後、以下の作業に入ってください!

audioカラムの追加

tweetsテーブルにstring型のaudioカラムを追加します。

ターミナル
$ rails generate migration AddAudioToTweets audio:string
ターミナル
$ rails db:migrate

このaudioカラムは音声ファイルのURL(住所)が書かれます。音声ファイル自体は別の場所に保存されます。

Index.html.erb

audioファイルを再生するコードを書きます

app/views/tweets/index.html.erb
    <% @tweets.each do |t| %>

        <%= audio_tag t.audio_url, :controls => true if t.audio? %>

    <% end %>

:controls => trueはコントローラパネルを表示します。
また、audio_tagには以下のオプションがあります。

:autoplay 自動再生
:loop ループ再生

ストロングパラメーター

audioパラメータを受け取れるようにストロングパラメーターに記述します。

tweets_controller.rb
# 割愛

private
def tweet_params
  params.require(:tweet).permit(:body, :audio)
end

new.html.erb

fileをuploadするコードを書きます。

app/views/tweets/new.html.erb

<%= form_for @tweet do |f| %>

  <div class="field">
    <%= f.label :audio %>
    <%= f.file_field :audio %>
  </div>

  <%= f.submit "Tweetする" %>
<% end %>

gemの追加

今回はcloudinaryと、carrierwaveというgemを使っていきます。Gemfileの一番下に以下を追加しましょう。

Gemfile
gem 'carrierwave'
gem 'cloudinary'
ターミナル
$ bundle install

carrierwave
cloudinary

それぞれのgemを簡単に説明すると
carrierwave : railsにてファイルのuploadができるようにするためのgem
cloudinary : 外部ストレージサービスのcloudinaryが利用できるようにするためのgem

アップローダーの作成

CarrierWaveのジェネレーターでアップローダーを作成します。以下のコマンドをターミナルに打ち込みましょう。

ターミナル
$ rails g uploader Audio

モデルの修正

app/models/tweet.rbを以下のように修正します。

app/models/tweet.rb
class Tweet < ApplicationRecord

# 追記ここから
  mount_uploader :audio, AudioUploader
# 追記ここまで

end

mount_uploader :audio, AudioUploaderは音声ファイルを指定の場所に保存することを表します。

次に保存場所を指定するアップローダの設定です。

app/uploaders/image_uploader.rbの6~8行目を変更しましょう。

app/uploaders/audio_uploader.rb
  # Choose what kind of storage to use for this uploader:
  storage :file
  # storage :fog

上記を下図のように変えます。

app/uploader/audio_uploader.rb
  # Choose what kind of storage to use for this uploader:
  if Rails.env.production?
    include Cloudinary::CarrierWave
    CarrierWave.configure do |config|
      config.cache_storage = :file
    end
  else
    storage :file
  end
  # storage :fog

cloudinaryは外部のストレージサービスです。本番環境(リリース後=production)ではcloudinaryに画像が保存され、それ以外(開発環境=ローカル)では自分のpcに保存されます。(publicフォルダー内に保存されます)

APIキーの非公開

Cloudinaryの各アカウントには「Cloud name」、「API Key」、「API Secret」が付与されています。

Cloudinaryマイページ

Cloudinaryのアカウントを外部に漏らさないためにセキュリティを強化します。

ここではdotenv-railsというgemを使っていきます。Gemfileの一番下に以下を追加しましょう。

Gemfile
gem 'dotenv-rails'
ターミナル
$ bundle install

と打ち込んでインストールします。

次に.envというファイルをアプリケーションディレクトリ(appやdbやGemfileがあるディレクトリ)に自分で作成します。
以下の図のようになっていればオッケーです。
※vendorフォルダーの中ではないので注意してください。

次に作成した.envファイルに以下を入力します。

.env
CLOUD_NAME=q0w9e8r7t6yu5  #←この値は人によって違います!!
CLOUDINARY_API_KEY=123456789012345 #←この値は人によって違います!!
CLOUDINARY_API_SECRET=1a2s3d4f5g6h7j8k9l0a1s2d4f5g6h1q #←この値は人によって違います!!

ここで「=」の後のそれぞれの値は先ほどのCloudinaryのマイページで取得したキーに書き換えてください(自分が取得したキーは絶対他言しないように!!また数字は個々人によって変わります)。
また、書き換える際は、コメントアウト部分を削除してください!

最後に隠しておきたいデータを定義した.envファイルを公開しないようにします。

.gitignoreに下記を追加します。
※もし.gitignoreファイルがない場合はアプリケーションディレクトリーにて作りましょう!

.gitignore
# 省略

/.env

これでOKです!

APIキーの利用

最後の手順です!
まずはconfigフォルダにcloudinary.ymlファイルを作成してください。

config/cloudinary.ymlに以下のようにそのままコピペしてください。

config/cloudinary.yml

development:
  cloud_name: <%= ENV['CLOUD_NAME'] %>
  api_key: <%= ENV['CLOUDINARY_API_KEY'] %>
  api_secret: <%= ENV['CLOUDINARY_API_SECRET'] %>
  enhance_image_tag: true
  static_file_support: false
production:
  cloud_name: <%= ENV['CLOUD_NAME'] %>
  api_key: <%= ENV['CLOUDINARY_API_KEY'] %>
  api_secret: <%= ENV['CLOUDINARY_API_SECRET'] %>
  enhance_image_tag: true
  static_file_support: false
test:
  cloud_name: <%= ENV['CLOUD_NAME'] %>
  api_key: <%= ENV['CLOUDINARY_API_KEY'] %>
  api_secret: <%= ENV['CLOUDINARY_API_SECRET'] %>
  enhance_image_tag: true
  static_file_support: false

これでAPIキーを非公開にしたまま利用することができました。

これにて、音声ファイルの投稿はできるようになりました。お疲れ様です(^^)/

公式ドキュメント

carrierwave
cloudinary
dotenv-rails