質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.62%

ActiveStorageで保存した画像の受け渡しが上手くいかずエラーが起きる

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 2,816

404notfound

score 12

前提・実現したいこと

ActiveStorageで保存した画像が上手く受け渡せていないようで、エラーが起きているのを解決し、保存した画像を表示させたいです。

RailsでSNSアプリを作成し、一度Herokuにデプロイしたところ問題なく作動していました。
公開後アイコン画像をアップロードしても一時的にしか保持されないことを知り、Active StorageとAWS S3を使い画像保存をさせようとしています。
S3への連携は上手くいき、元から作っていたアカウントのアイコン画像を編集してS3へ保存させたり、保存したアイコン画像を投稿一覧やユーザー詳細画面で表示することはできたのですが、以下の画面遷移でエラーが発生してしまいます。

①新しいアカウントを登録しようとして入力後に新規登録ボタンを押して情報を送信したとき
②ユーザー一覧を表示しようとしたとき

発生している問題・エラーメッセージ

①新しいアカウントを登録しようとして入力後に新規登録ボタンを押して情報を送信したとき

(:image以外は最初に作成したときからあって問題なく動いてたので、後から追加した:imageでエラーが起きていると思われます。)

ActiveSupport::MessageVerifier::InvalidSignature in UsersController#create
ActiveSupport::MessageVerifier::InvalidSignature
Extracted source (around line #20):

  def create
    @user = User.new( #ここが20行目
      name: params[:name],
      email: params[:email],
      password: params[:password],
      profile: "よろしくお願いします",
      image: "default_user.jpg"
    )

②ユーザー一覧を表示しようとしたとき

ArgumentError in Users#index
Showing /Users/UserName/Desktop/sample_app/app/views/users/index.html.erb where line #7 raised:

Can't resolve image into URL: to_model delegated to attachment, but attachment is nil
Extracted source (around line #7):

      <div class="users-index-item">
        <div class="user-left">
           <%= image_tag user.image %>  #ここが7行目
        </div>
        <div class="user-right">
          <%= link_to(user.name, "/users/#{user.id}") %>

該当のソースコード

①②共通
users_controller.rb(長くなるので関係なさそうなことは削っています)

class UsersController < ApplicationController

  def index
    @users = User.all.order(created_at: :desc)
  end

  def new
    @user = User.new
  end

  def create
    @user = User.new(
      name: params[:name],
      email: params[:email],
      password: params[:password],
      profile: "よろしくお願いします",
      image: "default_user.jpg"
    )

    if @user.save
      session[:user_id] = @user.id
      flash[:notice] = "ユーザー登録が完了しました"
      redirect_to("/users/#{@user.id}")
    else
      render("users/new")
    end
  end

def update
    @user = User.find_by(id: params[:id])
    @user.name = params[:name]
    @user.email = params[:email]
    @user.profile = params[:profile]

    if params[:image]
      @user.image = params[:image]
    end

    if @user.save
      flash[:notice] = "ユーザー情報を編集しました"
      redirect_to("/users/#{@user.id}")
    else
      render("users/edit")
    end
  end


①新しいアカウントを登録しようとして入力後に新規登録ボタンを押して情報を送信したとき
app/view/users/new.html.erb

仕様として最初にユーザー登録するときはプロフィールとアイコン画像は選べずデフォルトのもので登録されているようにしています。

<div class="main users-new">
  <div class="container">
    <div class="form-heading">新規ユーザー登録</div>
    <div class="form users-form">
      <div class="form-body">
        <% @user.errors.full_messages.each do |message| %>
          <div class="form-error">
            <%= message %>
          </div>
        <% end %>

        <%= form_tag("/users/create", {multipart: true}) do %>
          <p>ユーザー名</p>
          <input name="name" value="<%= @user.name %>">
          <p>メールアドレス</p>
          <input name="email" value="<%= @user.email %>">
          <p>パスワード</p>
          <input type="password" name="password" value="<%= @user.password %>">
          <input type="submit" value="新規登録">
        <% end %>
      </div>
    </div>
  </div>
</div>

②ユーザー一覧を表示しようとしたとき
app/view/users/index.html.erb

<div class="main users-index">
  <div class="container">
    <h1 class="users-heading">ユーザー一覧</h1>
    <% @users.each do |user| %>
      <div class="users-index-item">
        <div class="user-left">
           <%= image_tag user.image %> 
        </div>
        <div class="user-right">
          <%= link_to(user.name, "/users/#{user.id}") %>
        </div>
      </div>
    <% end %>
  </div>
</div>

試したこと

①新しいアカウントを登録しようとして入力後に新規登録ボタンを押して情報を送信したとき
エラー文より、User.new内に上手く認識されていない?カラムがあって、それが新しく加えた:imageで引っかかっていると思われるのですが、そこからどうすればいいかわかりませんでした。

最初のユーザー登録画面からプロフィールとアイコン画像も自分で登録できるようにすれば解決するかと思い、new.html.erbにもedit.html.erbと同様のコードで入力できるようにしてみたのですが、同じエラー文が出てしまい関係なかったので戻しました。

②ユーザー一覧を表示しようとしたとき
エラー文からuser.imageへ上手く受け渡せずnilになっているのが原因と思われるのですが、ここからどうすればいいかわかりませんでした。

補足情報(FW/ツールのバージョンなど)

edit.html.erbも一応貼っておきます。
登録済のアカウントはこのコードからアイコン画像を含めアカウント情報を問題なく変更できます。

また、他にも補足で貼ったほうがよいコードがありましたら、ご指摘いただければ幸いです。
よろしくお願いいたします。

app/view/users/edit.html.erb

<div class="main users-edit">
  <div class="container">
    <div class="form-heading">アカウント編集</div>
    <div class="form users-form">
      <div class="form-body">
        <% @user.errors.full_messages.each do |message| %>
          <div class="form-error">
            <%= message %>
          </div>
        <% end %>

        <%= form_tag("/users/#{@user.id}/update", {multipart: true}) do %>
          <p>ユーザー名</p>
          <input name="name" value="<%= @user.name %>">
          <p>メールアドレス</p>
          <input name="email" value="<%= @user.email %>">
          <p>アイコン画像</p>
           <%= file_field_tag :image %>
          <p>プロフィール</p>
          <input name="profile" value="<%= @user.profile %>">
          <input type="submit" value="保存">
        <% end %>


      </div>
    </div>
  </div>
</div>
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

+1

エラーが起きていた箇所を以下に変えたことでエラーが起きなくなり、想定した動きを実装できました!
アイコン画像を指定していないユーザーはデフォルトのアイコン画像を表示する仕様の実装方法を下記に変更したのがよかったようです。
投稿前:User.newで@user.imageにデフォルト画像を代入し、各ページで@user.imageでアイコン画像を表示
投稿後:User.newで@user.imageにnilを入れ、各ページで@user.imageに値が入っているか否かを判断する

①新しいアカウントを登録しようとして入力後に新規登録ボタンを押して情報を送信したとき
users_controller.rb

def create
    @user = User.new(
      name: params[:name],
      email: params[:email],
      password: params[:password],
      profile: "よろしくお願いします",
      image: nil
    )
end

②ユーザー一覧を表示しようとしたとき
app/view/users/index.html.erb

<% if user.image.attached? %>
          <%= image_tag user.image %>
          <% else %>
          <%= image_tag ("/default_user.jpg") %>
          <% end %>

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

checkベストアンサー

0

例えば、<img src="user.try(:image)">のように書くと、
imageがNilでもエラーにはならなず、imageがあれば表示されるようになると思います!

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/07/08 08:16

    ご回答ありがとうございます!

    app/view/users/index.html.erbのエラーを起こしていた箇所を<img src="user.try(:image)">に書き換えたところ、エラーが起きずに画面遷移できました!

    ただimageに何も入ってないみたいでアイコン画像が上手く表示されませんでした...
    もしアイコン画像を上手く表示させる方法についても案がありましたら教えていただけると幸いです。よろしくお願いいたします。

    キャンセル

  • 2019/07/08 09:09

    imageに何も入ってないのがDBやActiveStorageに保存されていないからか、
    保存はされているが呼び出しがうまくいっていないかが考えられそうです。
    こちらの記事が参考になるかもしれないので、原因を探ってみてください。。!
    https://railsguides.jp/active_storage_overview.html

    キャンセル

  • 2019/07/10 08:02

    ご返信が遅くなり申し訳ありません。

    教えていただいたサイトなど参考にしながら模索していたところ、User.newで@user.imageにnilを入れ、各ページで@user.imageに値が入っているか否かを判断する仕様に変えたことで無事にエラーなく実装できました!

    お話したなかでnilを代入することを思いついたので、回答していただいて本当に助かりました。ありがとうございます!

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.62%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る