Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

Railsチュートリアル 第14章 ユーザーをフォローする - ステータスフィード実装の動機と計画(データモデルの解説とテストの実装)

More than 1 year has passed since last update.

ステータスフィードのデータモデルの基本

例えば、「id 1のユーザーが、id 2、7、8、10のユーザーをフォローしている」という場合、フィードのデータモデルは、micropostsテーブルのサンプルデータとセットで示すと以下のようなイメージになります。

User_Feed.png

上図の矢印は、「現在のユーザー自身、および現在のユーザーがフォローしているユーザーに対応するユーザーidを持つマイクロポストを取り出す」という操作を表しています。

ステータスフィードの要求仕様と、それに対するテスト

ステータスフィードの要求仕様

どのように実装するかはさておき、この時点では、ステータスフィードの要求仕様として以下を示すことができます。

  • ログインユーザー自身のマイクロポストがステータスフィードに含まれていること
  • フォローしているユーザーのマイクロポストがステータスフィードに含まれていること
  • フォローしていないユーザーのマイクロポストがステータスフィードに含まれていないこと

上記要求仕様をアサーションとして展開し、テストを実装していきましょう。

「ステータスフィードを表示する」という機能の実装箇所

「ステータスフィードを表示する」という機能は、Userモデルにfeedメソッドとして実装したのでしたね。以下に現時点におけるapp/models/user.rb#feedの内容を示しておきます。

app/models/user.rb#feed
class User < ApplicationRecord
  has_many :microposts, dependent: :destroy
  # ...略
  def feed
    Micropost.where("user_id = ?", id)
  end
  #...略
end

ステータスフィードのテストの実装

前提条件として、以下のfixtureが存在するものとします。

test/fixtures/relationships.yml
one:
  follower: rhakurei
  followed: skomeiji

two:
  follower: rhakurei
  followed: rusami

three:
  follower: skomeiji
  followed: rhakurei

four:
  follower: mkirisame
  followed: rhakurei

上記fixtureからは、以下の関係があることがわかります。

  • rhakureiはrusamiをフォローしている
  • rhakureiはmkirisameをフォローしていない

この状況では、「rhakureiのステータスフィードには、rusamiとrhakureiのマイクロポストは見えるが、mkirisameのマイクロポストは見えない」というのが要求仕様通りの実装となります。

テストの対象はUserモデルなので、テストの実装箇所はtest/models/user_test.rbとなります。以下は実際のテストの実装内容です。

test/models/user_test.rb
require 'test_helper'

class UserTest < ActiveSupport::TestCase

  #...略

  test "feed should have the right posts" do
    rhakurei  = users(:rhakurei)
    mkirisame = users(:mkirisame)
    rusami  = users(:rusami)
    # フォローしているユーザーの投稿を確認
    rusami.microposts.each do |post_following|
      assert rhakurei.feed.include?(post_following)
    end
    # 自分自身の投稿を確認
    rhakurei.microposts.each do |post_self|
      assert rhakurei.feed.include?(post_self)
    end
    # フォローしていないユーザーの投稿を確認
    mkirisame.microposts.each do |post_unfollowed|
      assert_not rhakurei.feed.include?(post_unfollowed)
    end
  end
end

ステータスフィードのテストの実装に関する、マイクロポストのfixtureの注意事項

※上記テスト「feed should have the right posts」で使用する全てのユーザーについて、1つ以上のマイクロポストをtest/fixtures/microposts.ymlで定義しておく必要があります。1つもマイクロポストを定義していないユーザーがテスト「feed should have the right posts」に含まれていると、テスト「feed should have the right posts」はうまく動きません。

当該テストを初めて実装した時点における、ステータスフィードのテストの動作結果

現時点において、test/models/user_test.rbを対象としたテストの結果は以下のようになります。

# rails test test/models/user_test.rb
Running via Spring preloader in process 127
Started with run options --seed 63017

 FAIL["test_feed_should_have_the_right_posts", UserTest, 3.487605000000258]
 test_feed_should_have_the_right_posts#UserTest (3.49s)
        Expected false to be truthy.
        test/models/user_test.rb:103:in `block (2 levels) in <class:UserTest>'
        test/models/user_test.rb:102:in `block in <class:UserTest>'

  15/15: [=================================] 100% Time: 00:00:04, Time: 00:00:04

Finished in 4.55564s
15 tests, 27 assertions, 1 failures, 0 errors, 0 skips

テストは以下のコードで失敗しています。

test/models/user_test.rb(102〜104行目)
rusami.microposts.each do |post_following|
  assert rhakurei.feed.include?(post_following)
end

「ログインユーザー自身とは別の、フォローしているユーザーのマイクロポストがフィードに表示されていない」という理由でテストが落ちている、ということになりますね。

rapidliner00
* 現在のところは、エンジニアに憧れる非エンジニア * エンジニア的な業務効率化・改善に興味あり
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away