Oh!Coder

Coding Life

Acts_as_follower Gem简介

| Comments

今天跟大家分享的gem名叫acts_as_follower。实现的功能就是允许多个model之间互相follow。除此之外,还提供了block/unblock所follow的记录功能。基本上来说,比较适合开发类似于Github的follow系统。

安装

最新的主分支已经支持Rails 4。在gemfile中添加如下一行代码:

1
gem "acts_as_follower"

运行如下命令行:

1
rails generate acts_as_follower

对于Rails 3和Rails 2的支持,可参见原文档

使用

如果想让你的model能够被follow,需要在对应的model里添加一行代码:

1
2
3
4
5
6
7
8
9
10
11
class User < ActiveRecord::Base
  ...
  acts_as_followable
  ...
end

class Book < ActiveRecord::Base
  ...
  acts_as_followable
  ...
end

确保你的model能够follow其他的model,需要在model中添加如下一行代码:

1
2
3
4
5
class User < ActiveRecord::Base
  ...
  acts_as_follower
  ...
end

acts_as_follower方法

一个对象开始follow另一个对象:

1
2
3
book = Book.find(1)
user = User.find(1)
user.follow(book) # Creates a record for the user as the follower and the book as the followable

停止follow一个对象:

1
user.stop_following(book) # Deletes that record in the Follow table

检查某个对象是否正在follow另一个对象:

1
user.following?(book) # Returns true or false

获取一个user的所有follower数量:

1
user.follow_count # Returns an integer

获取所有尚未被block过的follow记录

1
user.all_follows # returns an array of Follow records

获取所有尚未被block并且正在follow的记录

1
2
user.all_following
# Returns an array of every followed object for the user, this can be a collection of different object types, eg: User, Book

根据特定类型获取follow记录

1
user.follows_by_type('Book') # returns an array of Follow objects where the followable_type is 'Book'

根据特定类型获取follow过的记录

1
user.following_by_type('Book') # Returns an array of all followed objects for user where followable_type is 'Book', this can be a collection of different object types, eg: User, Book

有一个method_missing方法来完善类似于following_by_type('Book')的方法:

1
user.following_users # exact same results as user.following_by_type('User')

根据特定类型获取follow记录的数量

1
user.following_by_type_count('Book') # Returns the sql count of the number of followed books by that user

与此对应的也有一个method_missing方法来获取特定类型的数量

1
user.following_books_count # Calls the user.following_by_type_count('Book') method

现在有一个可以返回follows级联的方法,级联的后缀可以是任何你想添加的可选项:

1
book.follows_scoped

这个方法并不是真实的follows方法,其实只是一个包括followable的一个级联,本质其实是:book.follows.unblocked.includes(:followable)

下面的方法有一个可选的ActiveRecord的hash参数(:limit,:order,等等)

1
follows_by_type, all_follows, all_following, following_by_type

acts_as_followable方法

获取所有被acts_as_followable修饰过的follower

1
book.followers  # Returns an array of all the followers for that book, a collection of different object types (eg. type User or type Book)

同样的,对于follower也有一些可选的后缀级联方法:

1
book.followers_scoped

同样的,这并不是返回真正的follower,只不过是一个包括follower的级联方法,本质上其实是:book.followings.includes(:follower)

获取follow的数目使用

1
book.followers_count

得到特定类型的follower,例如:所有类型为’User’的follower

1
book.followers_by_type('User') # Returns an array of the user followers

同样的也有一个method_missing方法来让此变的简单:

1
book.user_followers # Calls followers_by_type('User')

获取特定类型的follower数目

1
book.followers_by_type_count('User') # Return the count on the number of followers of type 'User'

同样,对于此也有一个method_missing与之对应

1
book.count_user_followers # Calls followers_by_type_count('User')

检查使用acts_as_follower的model是否follow了使用acts_as_followable的model,使用如下方法:

1
2
3
4
book.followed_by?(user)

# Returns true if the current instance is followed by the passed record
# Returns false if the current instance is blocked by the passed record or no follow is found

调用如下方法可以block一个follower

1
2
book.block(user)
# Blocks the user from appearing in the followers list, and blocks the book from appearing in the user.all_follows or user.all_following lists

实现unblock可以使用类似方法

1
book.unblock(user)

获取所有被block的记录

1
book.blocks # Returns an array of blocked follower records (only unblocked) (eg. type User or type Book)

如果你只需要被block的follower数量,可以使用如下方法

1
book.blocked_followers_count

解除block会删除所有曾经follow的记录,只要把:blocked的属性设置成false,相关信息就会被删除。所以user需要再次follow那个book。关于这一点,原作者也想听到其他解决方案。如果有更好的,他会把:blocked => false删除记录的方案替换掉。

下面的这个方法可以输入一个可选的ActiveRecord可选项参数(:limit,:order,等等)

1
followers_by_type, followers, blocks

Follow Model

Follow的model有一系列类似named_scope的集合。以备你想直接与Follow的model进行对接。

1
2
3
4
5
Follow.unblocked # returns all "unblocked" follow records

Follow.blocked # returns all "blocked" follow records

Follow.descending # returns all records in a descending order based on created_at datetime

下面的这个方法会拉取所有特定日子的记录。默认是两个星期,但是可以传入一个可选参数。

1
2
Follow.recent
Follow.recent(4.weeks.ago)

Follow.for_follower是一个命名级联,主要目的就是想在module中降低代码量,可以直接使用。它接受一个对象并且返回所有follower传进去的Follow记录。注意这将返回所有block和unblock的记录。

1
Follow.for_follower(user)

如果你并不需要block过的记录,只需要使用如下提供的方法:

1
2
3
user.all_follows
# or
user.all_following

Follow.for_followable扮演了与(for_follower)相同的功能。主要就是想减少重复,尽管如此也可以直接使用。这个方法可以传入一个被follow的对象,而且会返回所有Follow记录,其中包括可以被follow的记录。同样,这个方法会返回所有block和unblock的记录。

1
Follow.for_followable(book)

同样,如果你不需要被block的记录,使用如下的方法:

1
book.followers

如果你只需要block记录,用下面这个方法就可以

1
book.blocks

更多

更多更新的内容,详情可参见原文档

Comments