- 更新日: 2014年4月10日
- Rails
ActiveRecord Reputation System で「いいね!」機能を導入する
色んなソーシャルサイトに実装してある「いいね!」ボタンの機能。仕組みは分かるので一から実装もできるとは思うのですけど、activerecord-reputation-system という gem を見つけたのでそれを使ってみました。
ActiveRecord Reputation System
activerecord-reputation-system をインストール
Gemfile
1 |
gem 'activerecord-reputation-system' |
続いて以下の手順を実行。
1 2 3 4 5 |
$ bundle install $ bundle exec rails generate reputation_system $ bundle exec rake db:migrate |
のはずが、generate でいきなりエラー。
1 2 3 4 |
$ bundle exec rails generate reputation_system /path/to/rails_root/vendor/bundle/ruby/2.0.0/gems/activemodel-4.0.1/lib/active_model/deprecated_mass_assignment_security.rb:14:in `attr_accessible': `attr_accessible` is extracted out of Rails into a gem. Please use new recommended protection model for params(strong_parameters) or add `protected_attributes` to your Gemfile to use old one. (RuntimeError) |
activerecord-reputation-system が Rails3 までの attr_accessible を使用しているらしく、Rails4 で利用する場合は strong_parameters を使ってねとメッセージが出ています。
ということで、調べたら Rails4 の strong_parameters に対応した activerecord-reputation-system があったので、そちらを利用するように Gemfile を変更。
Gemfile
1 |
gem 'activerecord-reputation-system', github: 'NARKOZ/activerecord-reputation-system', branch: 'rails4' |
bundle install からやりなおし。
1 2 3 4 5 |
$ bundle install $ bundle exec rails generate reputation_system $ bundle exec rake db:migrate |
これで、インストールができマイグレーションも完了。
「いいね!」が付けられる対象のモデルに has_reputation を追加
ここではユーザーの投稿文 Post モデルがユーザー(User モデル)によって「いいね」されるという例を考えます。「いいね!」されるモデル(Post モデル)に以下のコードを追加する。
1 2 3 4 |
class Post < ActiveRecord::Base has_reputation :likes, source: :user, aggregated_by: :sum ... end |
:likes は評価の名前、ここは任意でなんでも良い。source には Post を「いいね」するモデル名を指定、ここでは User が Post を「いいね」するので :user を指定。.aggreated_by は、評価の方法を指定します。ここでは、単純に :sum(合計値)を指定。
驚きですが、たったこれだけで最低限の「いいね」機能が動作します。
activerecord-reputation-system の動作を pry で確認
以降、Rails 環境の pry で「いいね」機能の動作を試しました。出力されたSQLは省略してます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
$ bundle exec rails c Loading development environment (Rails 4.0.1) pry(main)> user1 = User.first pry(main)> post = Post.first pry(main)> post.add_evaluation(:likes, 1, user1) pry(main)> post.reputation_for(:likes).to_i ReputationSystem::Reputation Load (0.4ms) SELECT `rs_reputations`.* FROM `rs_reputations` WHERE `rs_reputations`.`reputation_name` = 'likes' AND `rs_reputations`.`target_id` = 1 AND `rs_reputations`.`target_type` = 'Post' LIMIT 1 => 1 pry(main)> post.add_evaluation(:likes, 1, user1) ActiveRecord::RecordInvalid: バリデーションに失敗しました。 Sourceはすでに存在します。 pry(main)> user2 = User.last pry(main)> post.add_evaluation(:likes, 1, user2) pry(main)> post.reputation_for(:likes).to_i ReputationSystem::Reputation Load (0.4ms) SELECT `rs_reputations`.* FROM `rs_reputations` WHERE `rs_reputations`.`reputation_name` = 'likes' AND `rs_reputations`.`target_id` = 1 AND `rs_reputations`.`target_type` = 'Post' LIMIT 1 => 2 |
pry で「いいね!」システムの基本が動作するのを確認できました。
1 2 3 |
post.add_evaluation(:likes, 1, user1) |
この部分が、user1 が post に「いいね」する動作です。add_evaluation メソッドは…
評価されるモデルのオブジェクト.add_evaluation(評価の名前, 評価で足す数字, 評価するモデルのオブジェクト)
となる。今回の例では「いいね!」機能が目的なので、単純に 1 を足しました。メソッド詳細は以下など参考。
https://github.com/twitter/activerecord-reputation-system/wiki/Evaluate-Models
1 2 3 |
post.reputation_for(:likes).to_i |
で、post が持つ「いいね」された数を取得できます。float で返ってくるので to_i。
また、一人目のユーザー(user1)が、同じ post に2回目のいいねをしようとしたら、バリデーションエラーが起こり重複いいねが避けられているのを確認できます。
user2 がいいねした後に、post の「いいね数」を post.reputation_for(:likes).to_i で取得すると、ちゃんと 2 に増えているのも確認しました。
素晴らしく簡単、今回は一応ここまでの導入と動作確認で終了です。コントローラーに like, unlike メソッドなどを作成したら、またブログにアップしようと思います。コントローラーを作るより、HTML と jQuery で「いいね!」ボタンのインターフェースを作るほうが大変そうな感触です。
- – 参考リンク –
- twitter – ActiveRecord Reputation System gem with Rails 4 – Stack Overflow
- ActiveRecord Reputation System Wiki
- #364 Active Record Reputation System – RailsCasts
- activerecord-reputation-systemでいいね!乞食になろう – リア充爆発日記
- Rails の関連記事
- RailsでMySQLパーティショニングのマイグレーション
- Rails ActiveRecordでdatetime型カラムのGROUP BY集計にタイムゾーンを考慮する
- RailsプラグインGemの作成方法、RSpecテストまで含めたrails pluginの作り方
- RailsでAMPに対応するgemをリリースしました
- Railsでrequest.urlとrequest.original_urlの違い
- Railsでwheneverによるcronバッチ処理
- Google AnalyticsのRails Turbolinks対応
- Railsアプリにソーシャル・シェアボタンを簡単設置
- Rails監視ツール用にErrbitをHerokuで運用
- Facebook APIバージョンのアップグレード手順(Rails OmniAuth)
Leave Your Message!