ぞえの技術めも

Ruby on Rails勉強中

【147日目】【1日20分のRailsチュートリアル】【第11章】マイクロポストを特定の順序で取得できるようにする

Ruby on Railsチュートリアル(第3版)

今日は「11.1.4 マイクロポストを改良する」から。

11.1.4 マイクロポストを改良する

具体的には、ユーザーのマイクロポストを特定の順序で取得できるようにしたり、マイクロポストをユーザーに依存させて、ユーザーが削除されたらマイクロポストも自動的に削除されるようにしていきます。

ふむふむ。

デフォルトのスコープ

まずデータベース上の最初のマイクロポストが、fixture内のマイクロポスト (most_recent) と同じであるか検証するテストを書いていきましょう (リスト11.13)。

まずテストを書いてみる。

test/models/micropost_test.rb

  test "order should be most recent first" do
    assert_equal microposts(:most_recent), Micropost.first
  end

リスト11.13では、マイクロポスト用のfixtureファイルからサンプルデータを読み出しているので、次のfixtureファイルも必要になります (リスト11.14)。

マイクロポスト用のfixtureファイルを作成する。

test/fixtures/microposts.yml

orange:
  content: "I just ate an orange!"
  created_at: <%= 10.minutes.ago %>

tau_manifesto:
  content: "Check out the @tauday site by @mhartl: http://tauday.com"
  created_at: <%= 3.years.ago %>

cat_video:
  content: "Sad cats are sad: http://youtu.be/PKffm2uI4dk"
  created_at: <%= 2.hours.ago %>

most_recent:
  content: "Writing a short test"
  created_at: <%= Time.zone.now %>

ほとんどのシステムでは上から順に作成されるので、fixtureファイルでも意図的に順序をいじっています。
(中略)
この振る舞いは恐らくシステムに依存していて崩れやすいので、(本来は) この振る舞いに依存したテストは書くべきでは無いでしょう。

崩れやすいからオススメではないしいつも使えるわけではない?けど、今回はとりあえず大丈夫なのかな…??

この段階ではマイクロポストをソートしてないのでテストは失敗する。

$ bundle exec rake test TEST=test/models/micropost_test.rb TESTOPTS="--name test_order_should_be_most_recent_first"
Finished in 0.11341s
1 tests, 1 assertions, 1 failures, 0 errors, 0 skips

残念ながらデフォルトの順序が昇順となっているので、このままでは数の小さい値から大きい値にソートされてしまいます (最も古い投稿が最初に表示されてしまいます)。
順序を逆にしたい場合は、一段階低いレベルの技術ではありますが、次のように生のSQLを引数に与える必要があります。

新しい投稿から古い投稿の順になるようソートする。

app/models/micropost.rb

  default_scope -> { order(created_at: :desc) }

これでテストが通るようになりました。

$ bundle exec rake test
Finished in 1.94684s
53 tests, 222 assertions, 0 failures, 0 errors, 0 skips

今日の学習時間は【25分】

次は「11.1.4 マイクロポストを改良する」の「Dependent: destroy」から。