GitHub の NewsFeed みたいな機能を実装したい
party_boy を使ってフォロー機能を実装したら、フォローしているユーザーのアクティビティを表示したい、と思うのは自然なことだよね。
NewsFeed みたいな機能を実装するための Rails プラグインに、『TimelineFu 』がある。
TimelineFu をインストール
RubyGems.org で公開されているバージョンは古くて、Rails3.2 に対応していない。GitHub のリポジトリにあるのが最新なので、GitHub からインストールする。
gem "timeline_fu", :git => "git://github.com/jamesgolick/timeline_fu.git"
を Gemfile に追加して
bundle
を実行。
ジェネレーターを実行して必要なファイルを作成
bundle exec rails g timeline_fu
を実行するとマイグレーションファイルと、TimelineEvent というクラスが生成される。
bundle exec rake db:migrate
でマイグレーション実行。
モデル作成時にアクティビティを保存してみる
fires メソッドを使って、保存するアクティビティの種類を指定できる。
class Entry < ActiveRecord::Base belongs_to :user # 新しい Enter を保存したときアクティビティを保存 fires :new_entry, :on => :create, :actor => :user end
上記では、新しい Entry を保存したタイミングで、timeline_events テーブルにアクティビティが保存される。
タイムラインを表示してみる
ここで残念なお知らせ。TimelineFu には、タイムラインを表示するためのビューやヘルパーは無い。TimelineFu が提供するのはアクティビティを保存するところのみ。割り切ってるなぁ。
無いものは仕方がない。自分で取得して表示するしかないな。今回は、簡単なユーザーのタイムラインにしてみる。
まずは TimelineFu のジェネレータで生成された TimelineEvent クラスに
class TimelineEvent < ActiveRecord::Base belongs_to :actor, :polymorphic => true belongs_to :subject, :polymorphic => true belongs_to :secondary_subject, :polymorphic => true scope :by_user, lambda { |user| where(:actor_type => user.class.name, :actor_id => user.id) } end
みたいなスコープを追加する。
コントローラーでユーザーのアクティビティを取得して、
class ProfilesController ... def show @profile = Profile.find(params[:id]) @user = profile.user @activities = TimelineEvent.by_user(@user) end ... end
ビューで出力。
<h2>News Feed</h2> <div class="timeline"> <% @activities.each do |activity| %> <%= activity.event_type %> <% end %> </div>
これで手抜きタイムラインの出来上がり。実際は event_type だけじゃなく、author や subject を整形して表示すると思う。
まとめ
TimelineFu を使ってアクティビティを保存するところまでは簡単に実装できた。ただ、肝心のタイムラインを表示する部分は自分で実装する必要があるけど。