railsチュートリアル第十四章 ステータスフィールド サブセレクト

##ステータスフィールド
現在のユーザーにフォローされているユーザーのマイクロポストの配列を作成し、現在のユーザー自身のマイクロポストと合わせて表示します。
このセクションを通して、複雑さを増したフィードの実装に進んでいきます。
これを実現するためには、RailsとRubyの高度な機能の他に、SQLプログラミングの技術も必要です。

###動機と計画
####ステータスフィードのテスト
test/models/user_test.rb

```rb
require 'test_helper'
.
.
.
  test "feed should have the right posts" do
    michael = users(:michael)
    archer  = users(:archer)
    lana    = users(:lana)
    # テストユーザー

    # フォローしているユーザーの投稿を確認
    lana.microposts.each do |post_following|
    # フィードを作成する
      assert michael.feed.include?(post_following)
      # マイケルのフィードにフォローが投稿されてるのが含まれているか？
    end
    # 自分自身の投稿を確認
    michael.microposts.each do |post_self|
      assert michael.feed.include?(post_self)
      # マイケルのフィードに自分自身も含まれているか？
    end
    # フォローしていないユーザーの投稿を確認
    archer.microposts.each do |post_unfollowed|
      assert_not michael.feed.include?(post_unfollowed)
      # フォローしていないものは含まれていないか？
    end
  end
end
```
####テスト
```
ubuntu:~/environment/sample_app (following-users) $ rails t
Running via Spring preloader in process 5728
Started with run options --seed 13331

 FAIL["test_feed_should_have_the_right_posts", #<Minitest::Reporters::Suite:0x000056391fee5aa8 @name="UserTest">, 3.5545889589998296]
 test_feed_should_have_the_right_posts#UserTest (3.56s)
        Expected false to be truthy.
        test/models/user_test.rb:131:in `block (2 levels) in <class:UserTest>'
        test/models/user_test.rb:129:in `block in <class:UserTest>'

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

Finished in 4.55511s
74 tests, 341 assertions, 1 failures, 0 errors, 0 skips
```
```  Expected false to be truthy.```


####とりあえず動くフィードの実装 
app/models/user.rb

```rb

```

#####テスト
```
ubuntu:~/environment/sample_app (following-users) $ rails t
Running via Spring preloader in process 7499
Started with run options --seed 53450

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

Finished in 4.11729s
74 tests, 378 assertions, 0 failures, 0 errors, 0 skips
```

####演習
1.
リスト 14.44において、現在のユーザー自身の投稿を含めないようにするにはどうすれば良いでしょうか? また、そのような変更を加えると、リスト 14.42のどのテストが失敗するでしょうか?

2.
リスト 14.44において、フォローしているユーザーの投稿を含めないようにするにはどうすれば良いでしょうか? また、そのような変更を加えると、リスト  14.42のどのテストが失敗するでしょうか?

3.
リスト 14.44において、フォローしていないユーザーの投稿を含めるためにはどうすれば良いでしょうか? また、そのような変更を加えると、リスト 14.42のどのテストが失敗するでしょうか? ヒント: 自分自身とフォローしているユーザー、そしてそれ以外という集合は、いったいどういった集合を表すのか考えてみてください。

###サブセレクト

####whereメソッド内の変数に、キーと値のペアを使う
app/models/user.rb

```rb
class User < ApplicationRecord
.
.
.
  # 試作feedの定義
  # 完全な実装は次章の「ユーザーをフォローする」を参照
  def feed
  # すべてのユーザーがフィードを持つので、feedメソッドはUserモデルで作るのが自然です
  Micropost.where("user_id IN (:following_ids) OR user_id = :user_id",
    following_ids: following_ids, user_id: id)    # following_ids フォローのユーザーidを取得
    # id 要素
    # whereメソッド テーブル内の条件に一致したレコードを配列の形で取得することができるメソッド
    # user_idを条件として取得することができる。
    # 上の疑問符があることで、SQLクエリに代入する前にidがエスケープされるため
    #   、SQLインジェクションと呼ばれる深刻なセキュリティホールを避けることができます。
    # SQL文に変数を代入する場合は常にエスケープする習慣をぜひ身につけてください。
  end
.
.
.
end
```

###フィードの最終的な実装
app/models/user.rb

```rb
class User < ApplicationRecord
.
.
.
  # 試作feedの定義
  # 完全な実装は次章の「ユーザーをフォローする」を参照
  def feed
  # すべてのユーザーがフィードを持つので、feedメソッドはUserモデルで作るのが自然です
    following_ids = "SELECT followed_id FROM relationships
                     WHERE follower_id = :user_id"
    Micropost.where("user_id IN (#{following_ids})
                     OR user_id = :user_id", user_id: id)    
    # following_ids フォローのユーザーidを取得
    # id 要素
    # whereメソッド テーブル内の条件に一致したレコードを配列の形で取得することができるメソッド
    # user_idを条件として取得することができる。
    # 上の疑問符があることで、SQLクエリに代入する前にidがエスケープされるため
    #   、SQLインジェクションと呼ばれる深刻なセキュリティホールを避けることができます。
    # SQL文に変数を代入する場合は常にエスケープする習慣をぜひ身につけてください。
  end
.
.
.
end
```
#####テスト
```
ubuntu:~/environment/sample_app (following-users) $ rails t
Running via Spring preloader in process 10510
Started with run options --seed 15480

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

Finished in 4.25870s
74 tests, 378 assertions, 0 failures, 0 errors, 0 skips
```