ActiveStorageとHerokuとCloudinaryで画像を保存してたら表示されなかった話(半分現在進行形)
【経緯】
Rails 5 & ActiveStorage & Cloudinary & Herokuで思いっきりハマった(そして、実際に完全に解決したわけではないが、とりあえず動くようにはなった)ので、メモっときます。
せっかく、Railsのデフォルトの機能として、データの保存機能がついたんだから、これは使うっきゃないよねと早速食指を伸ばしたわけですが、新しい機能使うのはリスクが伴いますね。
誰か、改善案あればご教示いただければ幸いです。
引き続き、独学Railsプログラマーです。
【環境】
Rails 5.2.3
activestorage 5.2.3
activestorage-cloudinary-service 0.2.3
cloudinary 1.11.1
activestorageのインストール、Cloudinaryの設定などの作業は完了しているものとする
【実装について】
ローカル開発環境では、ローカルに保存して、Herokuでの運用環境ではCloudinaryにデータを保存する。
その際、RailsのActiveStorageと連携して保存するようにする。
【ハマった内容】
ローカルでは全く問題なく動くし、Heroku上でも問題なく動いていると想っていました。
しかし、iOS端末(試すことができたのはiOS12.2 later)でファイルをアップロードすると、Cloudinaryには読み込まれるものの、view側で呼び出そうとすると、なぜか本来の保存場所と違うURLにリダイレクトされるという現象に遭遇しました。
【特に修正していない部分のコード 1】
app/model/product.rb
# ごく一部を抜粋 class Product < ApplicationRecord has_one_attached :image validates :image, attached: true, content_type: ['image/png', 'image/jpg', 'image/jpeg'] end
【特に修正していない部分のコード 2】
app/view/product/_form.html.erb
# ごく一部を抜粋 <%= form_with(model: product, local: true, class:"needs-validation", :html => {:novalidate => true}) do |form| %> ### 中略 ### <div class="field">↲ <p> <%=form.label ("商品一覧ページに表示されるサムネイル画像の登録"), autofocus: true, class: 'control-label' %><br> <%= form.file_field :image, class: 'form-field' %><br><small>(縦横300pxに切り抜かれます)</small> </p> </div> ### 中略 ### <div class="actions"> <%= form.submit "商品登録", class: 'btn btn-primary' %> </div> <% end %>
【動かなかったコード】
app/view/product/index.html.erb
# ごく一部を抜粋 <% @products.each do |product| %> ### 中略 ### <% if product.image %> <%= image_tag(product.image, class: "card-img-top") %> <% end %> ### 中略 ### <% end %>
【上記のコードの際の挙動】
・ローカル開発では問題なく画像が表示される
・Heroku上であっても、Macから写真をアップロードした場合、問題なく表示される。
・iOS端末からアップロードした場合でも、Cloudinary上にはimagesというフォルダ内に画像のアップロードは行われている。
・しかし、iOS端末からアップロードした写真を表示する際、なぜかrawフォルダのURLが発行され、表示されない。
【動いたコード】
app/view/product/index.html.erb
# ごく一部を抜粋 <% @products.each do |product| %> ### 中略 ### <% if product.image %> <% if Rails.env.production? %> <%= cl_image_tag(product.image.blob.key, class: "card-img-top") %> <% else %> <%= image_tag(product.image, :class => "card-img-top") %> <% end %> <% end %> ### 中略 ### <% end %>
【雑記】
とりあえず一旦動いているんですけど、has_one_attachedの中身とCloudinaryの連携の部分が100%理解できていないので、謎です。
Cloudinaryを使っていますし、まぁ別に本来の方法で呼び出しただけに見える気がしますが、viewの中に環境ごとでの場合分けのロジックとかが入って気持ちよくはないですね。
本来は、@product.imageだけでよしなにデータの保存先を変更してくれるはずなので、誰か改善策あればご教示いただければと思います。
ディスカッション
コメント一覧
まだ、コメントがありません