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

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

新規登録して質問してみよう
ただいま回答率
85.48%
Ruby

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

Ruby on Rails

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

Ruby on Rails 4

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

Q&A

解決済

1回答

2218閲覧

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

jusco

総合スコア80

Ruby

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

Ruby on Rails

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

Ruby on Rails 4

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

0グッド

0クリップ

投稿2015/07/31 16:32

編集2015/08/01 01:06

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

Ruby

1class Shop < ActiveRecord::Base 2 has_one :post, dependent: :destroy, foreign_key: 'id',autosave: true 3 has_reputation :likes, source: {reputation: :likes, of: :post}, aggregated_by: :sum 4end 5 6class Post < ActiveRecord::Base 7 belongs_to :shop, foreign_key: "id", autosave: true 8 has_reputation :likes, source: :user, aggregated_by: :sum 9end 10 11class User < ActiveRecord::Base 12 has_many :evaluations, class_name: "ReputationSystem::Evaluation", as: :source 13 14 def liked?(post) 15 evaluations.where(target_type: post.class, reputation_name: :likes, target_id: post.id).present? 16 end 17 18end

Ruby

1class PostsController < ApplicationController 2 before_action :authenticate_user!, only: :like 3 4 def like 5 @post = Post.find(params[:id]) 6 if params[:type] == "up" 7 value = 1 8 @post.add_or_update_evaluation(:likes, value, current_user ) 9 redirect_to :back, notice: 'お気に入りに追加しました' 10 else 11 @post.delete_evaluation(:likes,current_user) 12 redirect_to :back, notice: 'お気に入りから外しました' 13 end 14 end 15 16end

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

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

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

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

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


追記

2については、以下の様な記述で実装が出来ました。

Ruby

1class UserController < ApplicationController 2 def like_show 3 @posts = Post.evaluated_by(:likes, current_user) 4 end 5end 6

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


追記

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

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

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

よろしくお願いいたします。

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

rifuch

2015/08/01 00:36

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

回答1

0

ベストアンサー

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/01 22:09

rifuch

総合スコア1901

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

jusco

2015/08/02 10:18

ご回答ありがとうございます!! 全体的な指針を示して頂けたので、なんとか頑張ってみたいと思います! とりあえずメール送信については実装することが出来ました! 1つだけ追加でお尋ねしたいのですが、 >>「postのlike件数をいつ確認したか、あるいはpostのlikeが閲覧済みかの値」 とあるのですが、これらの値はどのような記述をすることで取得できるのでしょうか。 ご回答いただけると助かりますm(__)m よろしくお願いいたします。
rifuch

2015/08/02 12: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に変化が無ければ通知のカウントには入らなくなる、という仕掛けです。
jusco

2015/08/03 02: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
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問