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

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

ただいまの
回答率

90.61%

  • Ruby

    7345questions

    Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

  • Ruby on Rails

    7003questions

    Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

  • Ruby on Rails 4

    2406questions

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

【Rails】activerecord-reputation-systemで実装したお気に入り機能を拡張したいです。

解決済

回答 1

投稿 編集

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

jusco

score 72

activerecord-reputation-system というユーザー評価に使用できるgemを導入して、以下のようにお気に入りする機能を実装しました。

class Shop < ActiveRecord::Base
  has_one :post, dependent: :destroy, foreign_key: 'id',autosave: true
  has_reputation :likes, source: {reputation: :likes, of: :post}, aggregated_by: :sum
end

class Post < ActiveRecord::Base
  belongs_to :shop, foreign_key: "id", autosave: true
  has_reputation :likes, source: :user, aggregated_by: :sum
end

class User < ActiveRecord::Base
  has_many :evaluations, class_name: "ReputationSystem::Evaluation", as: :source

  def liked?(post)
    evaluations.where(target_type: post.class, reputation_name: :likes, target_id: post.id).present?
  end

end
class PostsController < ApplicationController
  before_action :authenticate_user!, only: :like

  def like
    @post = Post.find(params[:id])
    if params[:type] == "up"
    value = 1 
    @post.add_or_update_evaluation(:likes, value, current_user )
        redirect_to :back, notice: 'お気に入りに追加しました'
    else 
      @post.delete_evaluation(:likes,current_user)
          redirect_to :back, notice: 'お気に入りから外しました'
    end
  end

end

user は、shopが投稿したpostにお気に入り出来る、という機能です。
実際に上記の記述でお気に入り自体は正常に動作しています。


しかし、次に実装したい機能の実装方法がわかりません。

1.Postがお気に入りに追加された場合、そのPostの親Shopの管理画面にお気に入りにされた旨の通知を飛ばす。(画面内での表示)
2.Userは自分がお気に入りに追加したPost一覧表示できる


1.については、likeメソッドに何らかのアクションを入れることで通知できそうな気がするのですが、具体的な実装方法がわからずに困っています。
2.については、一覧画面を表示するメソッド内でcurrent_userにお気に入りされたpostの集まりである@postsをうまく取得できればいいかと思うのですが、その記述方法がわからずに困っています。


長くなってしまうかもしれませんが、
できるだけ具体的にご教示いただければ助かりますm(__)m
よろしくお願いいたします。


追記
2については、以下の様な記述で実装が出来ました。
class UserController < ApplicationController
  def like_show
         @posts = Post.evaluated_by(:likes, current_user) 
  end
end

1.についてはまだわからないので、是非ご教示いただきたいです。
よろしくお願いいたします。



追記
曖昧な質問で申し訳ありませんでした。

お気に入りに追加されたShopがログインしていた場合に、画面上部などに通知アイコンを表示し、そこをクリックすると通知情報が出るようにしたいです。
出来ればリアル・タイムでプッシュ通知のように、ページをリロードしなくても通知が届くとベストです。

また、通知があった場合に、その内容をAction Mailerを使ってShopのアドレスにメールが届くようにしたいです。
その際に、通知でメールが届く設定にするかどうかをShopが選べるようにも実装したと考えています。


よろしくお願いいたします。
  • 気になる質問をクリップする

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

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

  • rifuch

    2015/08/01 09:36

    単純に「通知」とおっしゃっていますが、「通知」の具体的な方法を示してみてください。たとえば、メールで通知を送信する、とか、画面上のアイコンにバッチをつけて通知する、とか。

    キャンセル

回答 1

checkベストアンサー

+1

activerecord-reputation-system自体を使ったことがないので、その周辺の処理についてはいまいちアドバイスできません。よって、コードは書けませんが、わかる範囲で回答したいと思います。

まず、1.の画面上部に通知アイコンを表示する方法ですが、
通知アイコンの状態を調べるメソッドをコントローラに実装し、
viewのjavascriptから定期的にremoteで問い合わせて通知の有無を更新するというのが一般的だと思います。

上記の実現のためには、postのlike件数をいつ確認したか、あるいはpostのlikeが閲覧済みかの値をどこかに保存しておく必要があるかと思います。

通知の表示を含むViewには、Javascriptで定期的にリモート問い合わせをするようにし、
対応するコントローラメソッドのビューには、
JSファイルで通知の表示部のノードを更新するようにしておき、
そこにpostの詳細を表示するリンクを埋め込んでおきます。
postの詳細を表示するコントローラメソッドあたりに閲覧済みかのフラグを更新する処理を入れておくといいかと。

ページの部分的な定期更新は、
Rails2時代にはperiodically_call_remoteというヘルパでうまいこと出来たのですが、
Rails3以降、Javascriptモジュールを実装側が選択できるようになったため、
このヘルパは使えなくなっています。
このあたりの記事が参考になるかと思います。

次に、1.のメール送信ですが、
Shopモデルにメール送信するか、送信するメールアドレスの値は何かを格納する属性か、
そのあたりの設定をまとめたモデルを作って、
PostControllerのlikeメソッドで問い合わせ、もしも送信する設定ならActionMailerでメール送信する、
という形が普通だと思います。
メールの送信に関してはRailsGuide ActionMailerの基礎あたりが参考になると思います。

あまり具体的に書けなくて申し訳ないですが、がんばってください。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2015/08/02 19:18

    ご回答ありがとうございます!!
    全体的な指針を示して頂けたので、なんとか頑張ってみたいと思います!
    とりあえずメール送信については実装することが出来ました!

    1つだけ追加でお尋ねしたいのですが、
    >>「postのlike件数をいつ確認したか、あるいはpostのlikeが閲覧済みかの値」
    とあるのですが、これらの値はどのような記述をすることで取得できるのでしょうか。

    ご回答いただけると助かりますm(__)m
    よろしくお願いいたします。

    キャンセル

  • 2015/08/02 21:00

    postを閲覧することで、通知がリセットされる仕様だと考えて回答しています。
    「postのlike件数をいつ確認したか、あるいはpostのlikeが閲覧済みかの値」は、postの属性として一つ追加することを考えています。

    likeにlikeした日時が格納されているのであれば、postに最終確認日時の値を格納するように属性を追加します。
    この場合、通知の確認の際には、postの最終確認日時以降のlikeを数えることで通知の有無を確認するようにします。
    postのshowをフックしてpostの最終確認日時を現在日時に更新してあげれば、それ以降likeの変更が無ければ通知のカウントには引っかからなくなります。

    likeにlikeした日時が格納されていない場合は、postに閲覧済みかどうかの真偽値のフラグを属性として追加します。
    フラグは、デフォルトでfalseとしておき、likeを変化させるメソッドでtrueにして保存、
    通知のチェックでは、フラグがtrueのpostを検索することで、未読のpostが得られます。
    postをshowするときに、フラグをfalseにして格納してあげれば、それ以降likeに変化が無ければ通知のカウントには入らなくなる、という仕掛けです。

    キャンセル

  • 2015/08/03 11:33

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

    likeした日時が格納されていないので、「postに閲覧済みかどうかの真偽値のフラグを属性として追加」するアプローチを取らせていただこうと思います!

    今回作成しようとしているアプリケーションでは、postにlikeされた場合以外にも通知が発生するタイミングがありそうなので

    ・「post_id」、「checked」カラムを持つnoticeモデルを作成
    ・PostがNoticeをhas_many
    ・Postに「notice_count」カラムを追加して、postに対応する notice.checked = false の
    数を格納
    ・likeされた場合にpost.noticeを作成し、デフォルトでpost.notice.checked = false で保存
    ・post.notice_count >= 1 の場合に、編集画面に通知を出す
    ・postが通知確認画面を開いた場合にpost.notices.checked を全てtrueにする & post.notice_count == 0 にする

    といった流れでの実装にチャレンジしてみたいと思います!!
    詳しく指針を示して頂いてありがとうございました!
    とてもわかりやすかったですm(_ _)m

    キャンセル

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

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

関連した質問

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

  • Ruby

    7345questions

    Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

  • Ruby on Rails

    7003questions

    Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

  • Ruby on Rails 4

    2406questions

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