GitHub の NewsFeed みたいな機能を実装するための Rails プラグイン『TimelineFu』を使ってみた

GitHub の NewsFeed みたいな機能を実装したい

party_boy を使ってフォロー機能を実装したら、フォローしているユーザーのアクティビティを表示したい、と思うのは自然なことだよね。

NewsFeed みたいな機能を実装するための Rails プラグインに、『TimelineFu 』がある。

Ruby Toolbox の Rails Activity Feeds カテゴリでも一番人気。今回はこれ使ってみる。

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 を使ってアクティビティを保存するところまでは簡単に実装できた。ただ、肝心のタイムラインを表示する部分は自分で実装する必要があるけど。