起こった問題
Railsチュートリアル第14章の最後の演習(14.3.3)の、feed
メソッドをjoins
を使ってリファクタリングするところで、サンプルコードをそのまま使ったところ、自身のmicropostが複数表示される不具合が出ました。
全然完成してません。
テーブルの結合をするとよくあることですね。
具体的にどういう結合になっているかは以下で解説されています。自力で考えてみたのですがややこしくて分かりませんでした...
【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
というメソッドがあるのでこいつを使います。
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の考えを実践させるための課題としてあえてそうしたのかも、と思えてきました。だとしたら粋ですね。