1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【Rails】テーブルを結合したら同じレコードが複数selectされたとき

Posted at

起こった問題

Railsチュートリアル第14章の最後の演習(14.3.3)の、feedメソッドをjoinsを使ってリファクタリングするところで、サンプルコードをそのまま使ったところ、自身のmicropostが複数表示される不具合が出ました。

スクリーンショット 2021-03-20 13.27.02.png

全然完成してません。
テーブルの結合をするとよくあることですね。
具体的にどういう結合になっているかは以下で解説されています。自力で考えてみたのですがややこしくて分かりませんでした...
【Rails】Active Recordのjoinsメソッドで連結したテーブルから一意なレコードを取得する(Rails Tutorial第14章) | LaptrinhX

該当のコードはこちら。

# ユーザーのステータスフィードを返す
  def feed
    part_of_feed = "relationships.follower_id = :id or microposts.user_id = :id"
    Micropost.joins(user: :followers).where(part_of_feed, { id: id })
  end

こう直す

重複を削除するには、後ろにdistinctをくっつけます。

Micropost.joins(user: :followers).where(part_of_feed, { id: id }).distinct

生SQLでも、SELECT DISTINCT microposts.* ...とすれば同じようになります。

ついでにテストにも重複したmicropostが表示されないことの確認を追加しましょう。
配列から重複を排除したものを返してくれるuniqというメソッドがあるのでこいつを使います。

user_test.rb

  test "feedに期待するmicropostが含まれる" do
    michael = users(:michael)
    lana = users(:lana)
    archer = users(:archer)
    
    # 割愛
    
    # 重複がない?
    assert_equal michael.feed.count, michael.feed.uniq.count    
  end

おわりに

バグに気づいたときは「著者のミスか?」と思ったのですが、最後の演習ですし、もしかしたらコラム1.2の考えを実践させるための課題としてあえてそうしたのかも、と思えてきました。だとしたら粋ですね。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?