Followers
relationships 的最後一塊拼圖就是增加與 user.following 相對應的 user.followers 方法。
從 Figure 12.7 可以發現,獲得關注使用者的對象所需的資料都已存在於 relationships table 中(我們要參考 Listing 12.7 中實現 active_relationships table 的方式)。
要實現的方法和實現使用者關注其他對象(followed users)的方式一樣,只要對調 follower_id 和 followed_id 的位置,以及把 active_relationships 換成 passive_relationships 即可。資料模型如 Figure 12.9 所示:
Figure 12.7: 透過「主動關係」獲得 Michael 關注的對象

Figure 12.9: 透過「被動關係」獲得關注 Michael 的對象

參考 Listing 12.8,我們可以使用 Listing 12.12 實現 Figure 12.9 的資料模型:
Listing 12.12: 使用「被動關係」實現 user.followers
app/models/user.rb
class User < ActiveRecord::Base
has_many :microposts, dependent: :destroy
has_many :active_relationships, class_name: "Relationship",
foreign_key: "follower_id",
dependent: :destroy
has_many :passive_relationships, class_name: "Relationship",
foreign_key: "followed_id",
dependent: :destroy
has_many :following, through: :active_relationships, source: :followed
has_many :followers, through: :passive_relationships, source: :follower
.
.
.
end
值得注意的是,其實我們可省略 followers 的 :source,簡寫成:
has_many :followers, through: :passive_relationships
可以省略的原因是,在這個例子中,:followers 屬性在 Rails 中會被轉成單數「follower」,然後自動尋找名為 follower_id 的 foreign key。
Listing 12.12 之所以保留 :source 是為了和 has_many :following 關聯的結構保持一致。
我們可以使用 followers.include? 方法測試資料模型,如以下 Listing 12.13 所示。Listing 12.13 也可以使用 followed_by? 方法補充 following 方法,不過目前應用中不需要。
Listing 12.13: 測試 followers 關聯
test/models/user_test.rb
require 'test_helper'
class UserTest < ActiveSupport::TestCase
.
.
.
test "should follow and unfollow a user" do
michael = users(:michael)
archer = users(:archer)
assert_not michael.following?(archer)
michael.follow(archer)
assert michael.following?(archer)
assert archer.followers.include?(michael)
michael.unfollow(archer)
assert_not michael.following?(archer)
end
end
Listing 12.13 只在 Listing 12.9 的基礎上增加了一行測試碼,但若想讓這個測試通過,很多事情要正確處理才行,所以足以測試 Listing 12.12 中的關聯。
現在執行測試,應該會通過(Green):
$ bundle exec rake test