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

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

ただいまの
回答率

90.10%

エラー nil:NilClass が解決できない

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 103

sakana-suki

score 8

前提・実現したいこと

deviseでログイン機能を作った後、全ユーザーを表示するusers/indexページを作りたいです。

経緯

railsチュートリアル10章を参考にしつつ、ユーザー一覧ページを作るために、DBをリセット後、gem faker(rails db:seed)を使ってユーザー数を増やし、成功しました(この時はusers/indexページはちゃんと機能していました)が、ログインできなくなってしまいました。

そこで、gem fakerの使用を一旦諦め、再度 rails db:migrate:reset して、手動でユーザー登録し直し
users/indexにアクセスすると

Showing /home/ec2-user/environment/insta-clone/app/views/users/show.html.erb 

undefined method `profile_photo' for nil:NilClass


と、エラーがでしまいました。
また、エラーが出ている個所は下記の二行目です。

 def avatar_url(user)
      return user.profile_photo unless user.profile_photo.nil?
      gravatar_id = Digest::MD5::hexdigest(user.email).downcase
    "https://www.gravatar.com/avatar/#{gravatar_id}.jpg"
  end


何故、userがnilになっているかよくわかりません。。

また、users/indexにアクセスすると、show.html.erbに関してエラーが出るが、ユーザーのプロフィール画面にusers/1 (←ユーザーiD)と直打ちしてアクセスするとshow.html.erbでエラーは出ないので更に???となっています。

Railsの仕組みが全体的にまだまだよくわからず、つながりが見えてきません。
どなたかエラー解決法など教えてくださると幸いです。

該当のソースコード

/insta-clone/app/helpers/application_helper.rb

module ApplicationHelper

  def avatar_url(user)
      return user.profile_photo unless user.profile_photo.nil?
      gravatar_id = Digest::MD5::hexdigest(user.email).downcase
    "https://www.gravatar.com/avatar/#{gravatar_id}.jpg"
  end

end

/insta-clone/app/views/users/show.html.erb

<div class="profile-wrap">
  <div class="row">
    <div class="col-md-4 text-center">
      <%= image_tag avatar_url(@user), class: "round-img" %>
    </div>
    <div class="col-md-8">
      <div class="row">
        <h1><%= @user.name %></h1>

        <% if @user == current_user %>
          <%= link_to "プロフィールを編集", edit_user_registration_path, class: "btn btn-outline-dark common-btn edit-profile-btn" %>
          <button type="button" class="setting" data-toggle="modal" data-target="#exampleModal"></button>
        <% end %>

        <div class="modal fade" id="exampleModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
          <div class="modal-dialog" role="document">
            <div class="modal-content">
              <div class="modal-header">
                <h5 class="modal-title" id="exampleModalLabel">設定</h5>
                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                  <span aria-hidden="true">×</span>
                </button>
              </div>
              <div class="list-group text-center">
                <%= link_to "サインアウト", destroy_user_session_path, method: :delete, class: "list-group-item list-group-item-action" %>
                <%= link_to "キャンセル", "#", class: "list-group-item list-group-item-action", "data-dismiss": "modal" %>
              </div>
            </div>
          </div>
        </div>
      </div>
      <% if @user == current_user %>
        <div class="row">
          <p>
            <%= @user.email %>
          </p>
        </div>
      <% end %>
    </div>
  </div>
</div>

ルーティングはこんな感じです

  Prefix Verb     URI Pattern                                                                              Controller#Action
                new_user_session GET      /users/sign_in(.:format)                                                                 users/sessions#new
                    user_session POST     /users/sign_in(.:format)                                                                 users/sessions#create
            destroy_user_session DELETE   /users/sign_out(.:format)                                                                users/sessions#destroy
user_facebook_omniauth_authorize GET|POST /users/auth/facebook(.:format)                                                           users/omniauth_callbacks#passthru
 user_facebook_omniauth_callback GET|POST /users/auth/facebook/callback(.:format)                                                  users/omniauth_callbacks#facebook
               new_user_password GET      /users/password/new(.:format)                                                            devise/passwords#new
              edit_user_password GET      /users/password/edit(.:format)                                                           devise/passwords#edit
                   user_password PATCH    /users/password(.:format)                                                                devise/passwords#update
                                 PUT      /users/password(.:format)                                                                devise/passwords#update
                                 POST     /users/password(.:format)                                                                devise/passwords#create
        cancel_user_registration GET      /users/cancel(.:format)                                                                  users/registrations#cancel
           new_user_registration GET      /users/sign_up(.:format)                                                                 users/registrations#new
          edit_user_registration GET      /users/edit(.:format)                                                                    users/registrations#edit
               user_registration PATCH    /users(.:format)                                                                         users/registrations#update
                                 PUT      /users(.:format)                                                                         users/registrations#update
                                 DELETE   /users(.:format)                                                                         users/registrations#destroy
                                 POST     /users(.:format)                                                                         users/registrations#create
                         sign_in GET      /sign_in(.:format)                                                                       users/sessions#new
                        sign_out GET      /sign_out(.:format)                                                                      users/sessions#destroy
                            root GET      /                                                                                        posts#index
                            user GET      /users/:id(.:format)                                                                     users#show
                      user_index GET      /users/index(.:format)                                                                   users#index
                     post_photos POST     /posts/:post_id/photos(.:format)                                                         photos#create
                      post_likes POST     /posts/:post_id/likes(.:format)                                                          likes#create
                       post_like DELETE   /posts/:post_id/likes/:id(.:format)                                                      likes#destroy
                   post_comments POST     /posts/:post_id/comments(.:format)                                                       comments#create
                    post_comment DELETE   /posts/:post_id/comments/:id(.:format)                                                   comments#destroy
                           posts GET      /posts(.:format)                                                                         posts#index
                                 POST     /posts(.:format)                                                                         posts#create
                        new_post GET      /posts/new(.:format)                                                                     posts#new
                            post GET      /posts/:id(.:format)                                                                     posts#show
                                 DELETE   /posts/:id(.:format)                                                                     posts#destroy
              rails_service_blob GET      /rails/active_storage/blobs/:signed_id/*filename(.:format)                               active_storage/blobs#show
       rails_blob_representation GET      /rails/active_storage/representations/:signed_blob_id/:variation_key/*filename(.:format) active_storage/representations#show
              rails_disk_service GET      /rails/active_storage/disk/:encoded_key/*filename(.:format)                              active_storage/disk#show
       update_rails_disk_service PUT      /rails/active_storage/disk/:encoded_token(.:format)                                      active_storage/disk#update
            rails_direct_uploads POST     /rails/active_storage/direct_uploads(.:format)                                           active_storage/direct_uploads#create

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

'rails', '~> 5.2.3' 
ruby 2.6.3

  • 気になる質問をクリップする

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

質問への追記・修正、ベストアンサー選択の依頼

  • unhappychoice

    2019/09/04 13:29

    UsersController はどうなっているでしょうか〜

    キャンセル

  • sakana-suki

    2019/09/04 14:24

    見ていただきありがとうございます。
    こんな感じになっています!


    ```
    class UsersController < ApplicationController
    before_action :authenticate_user!

    def index
    @users = User.paginate(page: params[:page], per_page: 10)
    end

    def show
    @user = User.find_by(id: params[:id])
    end

    end

    ```

    キャンセル

回答 1

checkベストアンサー

0

Userのインデックスページにアクセスしたいのであればusers/indexというパスではなく、/usersにアクセスしてください。
users/indexというパスでアクセスすることによってルーティングでのshowのパスであるusers/:idと誤認され、indexというidを持ったUserを探そうとしてしまうはずです。
おそらくコントローラーで@user = User.find_by(id: params[:id])と記述してあるため、この場合だと@user = User.find_by(id: 'index')というような形でUserを検索してしまい、@user = nilになってしまうために起こったエラーだと思われます。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2019/09/04 14:44

    回答ありがとうございます!くじけそうになっていました。。

    重ね重ね恐縮なのですが、
    現在のルーティングだと、/users にアクセスするとルーティングエラーになってしまいます。

    現在のroutes.rb が以下のようになっています。

    ------------------------------------------------------------------------------
    Rails.application.routes.draw do

    devise_for :users, :controllers => {
    :registrations => 'users/registrations',
    :sessions => 'users/sessions',
    :omniauth_callbacks => 'users/omniauth_callbacks'
    }

    devise_scope :user do
    get "sign_in", :to => "users/sessions#new"
    get "sign_out", :to => "users/sessions#destroy"
    end

    root 'posts#index'
    get 'users/:id', to: 'users#show', as: 'user'
    get 'users/index', to: 'users#index', as: 'user_index'

    resources :posts, only: %i(new create index show destroy) do
    resources :photos, only: %i(create)
    resources :likes, only: %i(create destroy)
    resources :comments, only: %i(create destroy)
    end

    end
    ---------------------------------------------------------------------------------

    この場合、
    get 'users/index', to: 'users#index', as: 'user_index'

    get 'users/', to: 'users#index', as: 'user_index'

    のように変更するのかな、行ごと削除かな、、、などといった改善案しか浮かばず(そしてうまくいきませんでした、、)、
    再度詰まってしまいました。

    haneru様の回答を読み、あっ!と思ったものの、うまく活かせません。どうしたらよいでしょうか

    キャンセル

  • 2019/09/04 15:10

    失礼しました。
    サーバーを止めてもう一度起動したら、ちゃんと全ユーザーが表示されました!

    get 'users/index', to: 'users#index', as: 'user_index'

    get 'users/', to: 'users#index', as: 'user_index'
    に変更で、よかったようです。

    本当に助かりました!ありがとうございます
    これからも勉強していきたいと思います。

    キャンセル

  • 2019/09/04 16:24

    今回の場合、showとindexだけですけど、今後、editやupdateなど増えてくると思います。
    そのため、書き方としては`resources :users, only: %i(index show)`の方がいいかもしれません。

    キャンセル

  • 2019/09/11 08:32

    気づくのが遅れてしまい、返信が遅くなりました(汗)
    確かにそちらの書き方のほうがすっきりとしていますね。
    役立つ修正をありがとうございます。

    キャンセル

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

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

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