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

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

ただいまの
回答率

90.32%

  • Ruby on Rails 4

    2465questions

    Ruby on Rails4はRubyによって書かれたオープンソースのウェブフレームワークです。 Ruby on Railsは「設定より規約」の原則に従っており、効率的に作業を行うために再開発を行う必要をなくしてくれます。

データの取得方法、eachメソッドについて

解決済

回答 2

投稿 編集

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

lapi

score 50

前提・実現したいこと

rails4 ローカル環境。

現在Pusherを使用し通知機能を実装しました。
通知機能自体は無事実装することができました。
teratailでいうと、ヘッダーのベルマークにお知らせのカウントが表示されるようにはできました。

そして、通知されたものを一覧ページで表示させたいと思ったのですが、一覧ページでのデータの取得方法が分かりません。

受け取るお知らせは「トピック」「タイムライン」の2つあり、どちらもNotificationモデルとアソシエーションしてあります。

現在記述しているコードはこちらです。

notifications_controller.rb

  def index
    # 自分の通知のみ取得、通知は新しい順に並び替える。
    @notifications = Notification.where(user_id: current_user.id).order(created_at: :desc)
  end

notifications/index.html.erb

<h2>お知らせ</h2>
 <% @notifications.each do |notification| %>
   <p>
       <%= notification.comment.user.try(:name) %>さんが
       あなたの投稿(<%= link_to "#{notification.comment.topic.title}", topic_path(notification.comment.topic, notification_id: notification.id) %>)にコメントしました。
   </p>
   <p>
       <%= notification.commenttl.user.try(:name) %>さんが
        あなたの投稿(<%= link_to "#{notification.commenttl.timeline.content}", timeline_path(notification.commenttl.timeline, notification_id: notification.id) %>)にコメントしました。
   </p>
 <% end %>

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

現在のnotifications/index.html.erbでの記述では

ActionView::Template::Error (undefined method `user' for nil:NilClass):


とエラーになってしまいます。

トピックとタイムラインどちらかだけのデータなら取得して表示はできるのですが、どちらのお知らせも表示する方法が分かりません。

こういう場合はそもそもeachメソッドではなく違うメソッドを使ったりするのでしょうか?

説明が分かりづらい点もあるかとは思いますが、ご教授のほどよろしくお願いします。

補足

notificationsテーブル

  create_table "notifications", force: :cascade do |t|
    t.boolean  "read",         default: false
    t.integer  "user_id"
    t.integer  "comment_id"
    t.datetime "created_at",                   null: false
    t.datetime "updated_at",                   null: false
    t.integer  "commenttl_id"
  end

  add_index "notifications", ["comment_id"], name: "index_notifications_on_comment_id", using: :btree
  add_index "notifications", ["commenttl_id"], name: "index_notifications_on_commenttl_id", using: :btree
  add_index "notifications", ["user_id"], name: "index_notifications_on_user_id", using: :btree

下記のようにトピック、あるいはタイムラインのみを取得すると、どちらかのデータは正常に表示はできます。
下記の場合はトピックに関するお知らせのみ表示されます。

notifications/index.html.erb

<h2>お知らせ</h2>
 <% @notifications.each do |notification| %>
   <p>
       <%= notification.comment.user.try(:name) %>さんが
       あなたの投稿(<%= link_to "#{notification.comment.topic.title}", topic_path(notification.comment.topic, notification_id: notification.id) %>)にコメントしました。
   </p>
 <% end %>
  • 気になる質問をクリップする

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 2

checkベストアンサー

+1

DB設計(Model定義)ミスかと思います。
とりあえず

<h2>お知らせ</h2>
 <% @notifications.each do |notification| %>
       <%= (content_tag :p ,"#{notification.comment.user.try(:name)}さんが
       あなたの投稿#{<%= (link_to notification.comment.topic.title, topic_path(notification.comment.topic, notification_id: notification.id)})にコメントしました。") if notification.comment.present? %>
       <%= (content_tag :p ,"#{notification.commenttl.user.try(:name)}さんが
        あなたの投稿(#{<%= (link_to notification.commenttl.timeline.content, timeline_path(notification.commenttl.timeline, notification_id: notification.id)})にコメントしました。") if notification.commenttl.present? %>
 <% end %>


というふうにすれば、とりあえず思い通りの結果が表示されると思います。
あまりスマートではないですが。

もし必要なら、別質問を立て、各モデルを晒してくださればリファクタリングのお手伝いもできますが。。

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2017/03/14 15:11

    ご回答ありがとうございます。
    確かにmokeさんのご指摘通り修正したら表示はできました。

    お知らせがない場合は空の値で表示されてしまい思うようにはいきません。

    別質問を立て、各モデルを記載させて頂きますので、ぜひリファクタリングのお手伝いして頂けると嬉しいです。

    別質問立て終わりましたら、再度こちらでコメントさせて頂きます。

    キャンセル

  • 2017/03/14 15:28 編集

    一応レイアウトに関してはp tagをどうにかすればいいので
    回答修正するので再度試してみてください

    キャンセル

  • 2017/03/14 15:39

    回答修正までありがとうございます。
    再度そちらでも試しています。

    https://teratail.com/questions/69071?modal=q-comp
    こちらの方で新しく質問を立てましたので、お時間があるときに改めてご教授いただけると嬉しいです。

    よろしくお願いします。

    キャンセル

0

userメソッドが定義されていないというエラーが出ています。
データベースの構造がわからないので具体的なことは何も言えないのですが、下記の部分が間違っているのではないでしょうか?

notification.comment.user

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2017/03/14 15:05

    ご回答ありがとうございます。
    データベースのnotificationsテーブルに関して追記させて頂きました。

    現状、トピックあるいはタイムラインのどちらかのみのお知らせを取得する場合は
    notification.comment.user
    で取得できるのですが、2つのお知らせを取得すると質問したようなエラーになってしまいます。

    キャンセル

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

  • Ruby on Rails 4

    2465questions

    Ruby on Rails4はRubyによって書かれたオープンソースのウェブフレームワークです。 Ruby on Railsは「設定より規約」の原則に従っており、効率的に作業を行うために再開発を行う必要をなくしてくれます。