KATUUUNs blog

プログラミング学習で得た知識をアウトプットするためのブログです

学習48日目 RailsといくつかのGemを用いて音声投稿機能を実装する流れ

こんにちは。KATUUUNです。引き続きオリジナルアプリを作成しています。
作成にあたって、音声投稿機能を実装したくなったため、その手順を忘れないためにアウトプットしておきます。

  • 背景
  • 前提
  • 手順
  • 背景 

現在オリジナルアプリ作成中です。その中でプログラミング学習に特化した単語帳アプリを作成中です。自分だけの単語帳を作るために、投稿機能を実装しました。そこで単語(keyword)とともに自分が録音した音声も投稿できたら、学習の質が上がるのではないかと思いました。

  • 前提

バージョン:Rails 6.0.0
*今回は録音機能ではなく、音声投稿機能を実装する。録音アプリとMP3への変換アプリはAppStoreからインストールしました。
*単語帳アプリ作成にあたり、ユーザー管理機能、単語投稿機能(keywordsテーブル)は実装済みです。

  • 手順


カラムの追加

rails generate migration AddAudioToKeywords audio:string

その後いつものrails db:migrateを実行する。
これでkeywordsテーブルにstring型のaudioカラムが作成されました。
※ここで保存されるのは音声ファイルのURLです。音声自体は別の場所に保存されます。


ファイルをアップロードするビューファイル作成

app>views>keywords>_form.html.erb

# 途中省略
<%# 音声 %>
      <div class="audio-upload">
        <div class="form-title">
          音声ファイル
        </div>
        <div class="audio-form">
          <%= f.file_field :audio %>
        </div>
      </div>

<%= f.file_field :audio %>と記述しました。<%= f.label :audio %>を追加してもいいと思います


コントローラー追加
audioカラムを追加します。

keywords_contoroller.rb

private
  def keyword_params
    params.require(:keyword).permit(:word, :genre_id, :instruction, :audio).merge(user_id: current_user.id)
  end

私はprivateメソッド内のストロングパラメータ内に書きました。

また、私の場合、modelファイルにバリデーションはかけていません。


表示させるビューファイル作成

app>views>keywords>show

# 途中省略
<% @keywords.each do |keyword| %>

#省略
      <td>
        <% if keyword.audio.present? && keyword.user_id == current_user.id %> 
          <%= audio_tag keyword.audio_url, :controls => true %>
        <% end %>  
      </td>

私の場合はtableタグの中に書きました。audio_tag keyword.audio_urlが最低限必要。
:controls => trueはオプションの一つで、再生ボタンが表示できる。他にも自動再生とかループ再生とかいろんなオプションがあります。


こっからややこしいところ

gemの追加

gem 'carrierwave'
gem 'cloudinary'

その後いつものbundle install


carrierwaveでアップロード機能が実装できる
cloudinaryは本番環境で音声を保存できる

アップローダー作成

rails g uploader Audio

ターミナルに打ち込みます


保存先変更
モデルファイルにて保存先をAudioUploaderに変更

app>models>keyword.rb

# 途中省略 
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に保存され、
開発環境(ローカル)では自分のpublicフォルダー内に保存されます


非公開APIの設定
以下からアカウントを作成しましょう
https://cloudinary.com/console/welcome

https://i.gyazo.com/d063e63798c1335b17e7fa1a43676918.jpg

dashboardにあるCloud name、API Key、API Secretを控えておきます。


セキュリティを強化
Cloudinaryのアカウントを外部に漏らさないためにdotenv-railsというgemを使います

gem 'dotenv-rails'

毎度お馴染み bundle installします



envファイル作成
アプリケーションディレクトリ(appやdbやGemfileがあるディレクトリ)に自分で作成します。
https://i.gyazo.com/dbcf3455ea083b863ff663f4c656a474.png
上のようにファイルを作ります



.envファイル入力

.env
CLOUD_NAME=*************
CLOUDINARY_API_KEY=**********
CLOUDINARY_API_SECRET=***********

先ほどのCloudinaryのマイページで取得したキー「=」の後のそれぞれの値にします



隠しておきたい.envファイルを公開しないようにする。

.gitignoreに下記を追加

.gitignore
# 省略

/.env


APIキーの利用
まずは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キーを非公開にしたまま利用することができます。

これで音声投稿機能が実装できます。