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

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

ただいまの
回答率

87.77%

Rails4.2 お知らせ一覧の作り方

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 2
  • VIEW 1,732
退会済みユーザー

退会済みユーザー

teratailのお知らせ一覧のような機能を作ったのですが、我ながらクソだな。。と思い作り直したいのですが、アドバイスを下さい

現状
itemに質問などのアクションが起きた際に、notificationをレコードを発行し、それをnotification contorollerで集めて、view側で対応する文言を当てはめています。

問題点
① notificationのレコード数が10万、100万になった場合のパフォーマンス
(多分まともに動かない気がする)
② 未読数を表示するためにapplication.html.erbに書いたコードが毎回呼び出されるのでパフォーマンスが。。
③view側で文言を振り分けているのがよくない気がする。。がどうしていいかわからない



#application.html.erb
<!-- お知らせ一覧 -->
              <li>
                <a href="/notifications/">
                  <i class="fa fa-bell-o"></i>
                  <!-- Indicator with number -->
                  <% if @recent_notifications_activity.present? %>
                      <span class="navbar-new"><%= @recent_notifications_activity.count %></span>
                  <% end %>
                </a>
              </li>



#notifications/index.html.erb
<% @notifications.each do |comment| %>

<!-- 質問 -->
          <% if comment.body_num == 10000 %>
              <a href="<%= item_url(comment.item_id) %>" class="list-group-item">
                &ensp;<i class="fa fa-comment-o"></i>&ensp;
                <small>アイテムに<%= comment.item.title%>に<%= comment.originator.profile.user_name%>さんが質問しました。</small>
                <p class="palette-paragraph text-right"><small><i class="fa fa-clock-o"></i>&ensp;<%=date_format(comment.created_at) %></small></p>
              </a>
          <% end %>
<!-- アイテムが更新されました -->
<!-- 削除されました。 -->
<% end %>
#notification controller
class NotificationsController < ApplicationController

  # GET /notifications
  # GET /notifications.json
  def index
    @user = current_user.id
    @notifications = Notification.where("(recipient_id = ?)  OR (body_num = ?)", @user, 80000)
                            .order(created_at: :desc)
                            .includes(:item).includes(:originator => :profile)
                            .page(params[:page]).per(15)
    #アクセスフラグ
    @notifications.update_all({status: true})
  end

  private
    # Never trust parameters from the scary internet, only allow the white list through.
    def notification_params
      params.require(:notification).permit(:status, :originator_id, :recipient_id, :item_id, :navi_id)
    end
end
#notification db migrate
class CreateNotifications < ActiveRecord::Migration
  def change
    create_table :notifications do |t|
      t.integer :originator_id # 発信者のuser_id
      t.integer :recipient_id    # 受信者のuser_id
      t.integer :item_id          #   アイテム
      t.integer :body_num     # 対応する文言
      t.boolean :status          # 閲覧フラグ
      t.timestamps
    end
    add_index :notifications, :item_id
    add_index :notifications, :originator_id
    add_index :notifications, :recipient_id
  end
end
  • 気になる質問をクリップする

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 1

checkベストアンサー

+1

① notificationのレコード数が10万、100万になった場合のパフォーマンス 
(多分まともに動かない気がする) 

実際に10万件レコードをセットして試してみるのがよいと思います。

見た感じ"(recipient_id = ?)  OR (body_num = ?)"の部分でデータベースのインデックスが効かず遅くなるかもしれないと感じました。


② 未読数を表示するためにapplication.html.erbに書いたコードが毎回呼び出されるのでパフォーマンスが。。 

パフォーマンスが問題になったらキャッシュするのがよいと思います。

雑なやり方であれば、sessionに未読数と最終更新時刻を保存させて、それを表示させます。
最終更新時刻が1日より前なら(適当です)一致してないかもしれないので更新する。
NotificationsControllerindexアクションが呼ばれた時も更新する。
という方法はどうでしょう。

あるいは真面目にUserモデル内に未読件数というフィールドを作り、NotificationsControllerindexアクションで更新するなどです。


③view側で文言を振り分けているのがよくない気がする。。がどうしていいかわからない 

どこを懸念しているのかわかりませんが、見た感じ問題ないように見えます。

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2015/07/06 21:26

    お礼が遅くなり申し訳有りませんでした。特に②が参考になり感謝しています。

    キャンセル

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

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

関連した質問

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