すでに情報が腐るほどあるフォロー機能ですが、理解を深めるためにも、
自分の言葉でまとめ直してみます。
Rails で、 Twitter や app.net などにある、ユーザーどうしのフォロー機能を
実装したいとします。
どうやら、いい感じの gem が存在しているようですが、今回は使わない方針で。
フォロー機能を実装しようと思うと、ユーザーとユーザーの多対多の関係となるため、
以下の様な DB 構成になると思います。
(Relation
は中間テーブル)
User Relation User +----------------+ +--------------------+ +------- | id: integer | | target_id: integer | | id: | name: string +--+ from_id: integer +--+ name: | ... | | | | ... +----------------+ +--------------------+ +-------
UserA(id:1)
は UserB(id:2)
をフォローした場合は、
Relation
に target_id: 2, from_id: 1
が挿入される感じです。
ということで、早速実装。
モデルを作って。
$ rails g model relation
マイグレーションファイルをいじる。
class CreateRelations < ActiveRecord::Migration def change create_table :relations do |t| t.integer target_id, null: false t.integer from_id, null: false end end end
そして適用。
$ bundle exec rake db:migrate
次に、 Model に has_many
とかつけていきます。
class User < ActiveRecord::Base has_many :follows_f, class_name: 'Relation', foreign_key: :from_id has_many :followings, through: :follows_f, source: 'target' has_many :followers_f, class_name: 'Relation', foreign_key: :target_id has_many :followers, through: :followers_f, source: 'from' # ... end
中間テーブルも。
class Relation < ActiveRecord::Base belongs_to :target, class_name: 'User', foreign_key: 'target_id' belongs_to :from, class_name: 'User', foreign_key: 'from_id' end
これで、上に示した DB の関連を実装できました。
次に、フォローなどの機能を追加していきます。
class User < ActiveRecord::Base ... def follow user followings << user end def unfollow user followings.destroy user end def followed? user followings.include? user end def follower? user user.followers.include? user end end
これでおわり。