0
0

[rails & cloudinary]carrierwaveで詰まるのでActive Storage で画像投稿を実装する

Last updated at Posted at 2024-05-25

経緯

railsにてcloudinaryとcarrierwaveを用いて画像投稿を実装していたのですが、どうやら最近carrierwaveが上手く動いていないようでローカルにそのまま画像が保存されたり、Errno::EACCES in HogesController#create Permission denied @ apply2files -の様なエラーが出てるようで。。。。

Active Storageを利用すれば無事投稿が出来たので備忘録として残しておきます。

本記事の想定

  • cloudinaryのアカウント登録が完了している
  • 投稿機能が実装済み
  • 環境変数はgem 'dotenv-rails'で管理

※rails6.1.7 ruby3.0.4を使用しています。
(rails7.1.3 ruby3.3でも動作確認済み)

実装

Active Storageの詳しい仕様ついては公式ドキュメントで確認して下さい。

Active Storageの導入

ターミナルまたはコマンドプロンプト
$ rails active_storage:install
$ rails db:migrate

実際にアップロードしたファイルが保存されるテーブルactive_storage_blobsや、active_storage_attachmentsという中間テーブルが作成されます。

config/storage.ymlの編集

config/storage.ymlファイルにCloudinary用の設定を追加します。

config/storage.yml
cloudinary:
  service: Cloudinary
  cloud_name: <%= ENV['CLOUD_NAME'] %>
  api_key: <%= ENV['CLOUDINARY_API_KEY'] %>
  api_secret: <%= ENV['CLOUDINARY_API_SECRET'] %>

環境変数名は.envに書かれている内容を合わせてください。

インデントは編集しないようにしてください、

development.rb production.rbの編集

開発環境での画像保存を設定する場合development.rb、本番環境の場合はproduction.rbを編集してください。

変更前

config/environments/development.rb
  config.active_storage.service = :local

変更後

config/environments/development.rb
  config.active_storage.service = :cloudinary

production.rbも同様に編集してください。

Gemのインストール

Gemfile
gem 'cloudinary'
gem 'activestorage-cloudinary-service'
ターミナルまたはコマンドプロンプト
bundle install

モデルの編集

画像を保存するカラムを用意します。テーブルに新しくカラムを追加する必要はなく、投稿機能を実装しているモデル(本記事ではTweetモデル)に画像を保存する用のカラム(本記事ではphoto)を記述するだけで大丈夫です。

既にテーブルに作成しているカラム名とは違う名前を記述してください。
例えば、「imageカラムを既に作ってるのでそれを使おう!」みたいな事が出来ないという事です。

tweet.rb
class Tweet < ApplicationRecord
  has_one_attached :photo #追記
end

わざわざテーブルにカラムを追加する必要がないのは便利ですね。

view,controllerの編集

コントローラ(本記事の場合はtweets)にてストロングパラメータにphotoカラムを追加

コントローラ
  private

  def tweet_params
    params.require(:tweet).permit(:title, :body, :photo) #photoを追加
  end

投稿と表示のviewファイルを編集

new.html.erb
<%= form_for @tweet do |f| %>
<div class="field">
    <%= f.label :photo %> #追記
    <p><%= f.file_field :photo %></p> #追記
</div>
<%= f.submit "投稿する" %>
<% end %>
index.html.erb
<% @tweets.each do |t| %>
    #追記ここから
    <% if t.photo.attached? %>
        <%= image_tag t.photo, size: '250x200'%>
    <% end %>
    #追記ここまで
<% end %>

あとがき

実装は以上ですお疲れ様でした。

本記事では一つの画像を投稿する方法のみを扱いましたが、複数画像を投稿する方法もあるので是非トライしてみてください。

以下、お世話になった記事です。ありがとうございました。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0