railsチュートリアル第１３章 マイクロポストを改良する

###マイクロポストを改良する
#####デフォルトのスコープ
新しい順にマイクロポストを表示させる。
そのためにdefault scopeというテクニックを使う。

####マイクロポストの順序付けをテストする
test/models/micropost_test.rb

```rb
require 'test_helper'
.
.
.
  test "order should be most recent first" do
    assert_equal microposts(:most_recent), Micropost.first
    # microposts(:most_recent) データベース上の最初のマイクロポスト
    # Micropost.first fixture内のマイクロポスト
    # 上二つが等しいか？
    # マイクロポストのfixtureがあるという前提に依存しています。
  end
end
```

####マイクロポスト用のfixture
test/fixtures/microposts.yml

```
orange:
  content: "I just ate an orange!"
  created_at: <%= 10.minutes.ago %>
  user: 
  # ユーザーfixtureにある対応ユーザーに関連付けることをRailsに指示できます。

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

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

most_recent:
  content: "Writing a short test"
  created_at: <%= Time.zone.now %>
  user: michael
```
####default_scopeでマイクロポストを順序付ける
app/models/micropost.rb

```rb
class Micropost < ApplicationRecord
# ApplicationRecordを継承したモデルが作られます
  belongs_to :user
  # userモデルとの間に「1対1」のつながりが設定
  # 割り当てる
  default_scope -> { order(created_at: :desc) }
  # データベースから要素を取得したときの、
  #   デフォルトの順序を指定するメソッドです。
  # order(created_at:desc) でこのカラムの順序に指定する
  # デフォルトで最も古い投稿が最初に投稿が表示されている。
　# :desc 新しい投稿から古い投稿の順になります
　# -> ラムダ式という。
  validates :user_id, presence: true
  # presence これは存在するか
  # presenceメソッドはオブジェクトが存在すればそのオブジェクトを返し、
  #   オブジェクトが存在しなければnilを返すメソッドとなります
  validates :content, presence: true, length: { maximum: 140 }
  # 最大１４０文字まで
end
```

```rb
>> -> {puts "foo" }
=> #<Proc:0x000055622fc512c8@(irb):1 (lambda)>
>> -> {puts "foo" }.call
foo
=> nil
```

#####Dependent: destroy
####マイクロポストは、その所有者（ユーザー）と一緒に破棄されることを保証する
app/models/user.rb

```rb
class User < ApplicationRecord
  has_many :microposts, dependent: :destroy
  # 他のモデルとの間に「1対多」のつながり
  # has_many関連付けが使われている場合、
  #   「反対側」のモデルでは多くの場合belongs_toが使われます。
  # dependent: :destroy
  # ユーザーが破棄された場合
  #   、ユーザーのマイクロポストも同様に破棄される。
.
.
.
end
```

####dependent: :destroyのテスト
test/models/user_test.rb

```rb
require 'test_helper'

class UserTest < ActiveSupport::TestCase
  def setup
    @user = User.new(name: "Example User", email: "user@example.com",
                     password: "foobar", password_confirmation: "foobar")
  end
.
.
.
  test "associated microposts should be destroyed" do
  # マイクロポストがユーザーと一緒に破棄されたかテスト
    @user.save
    # 保存する
    @user.microposts.create!(content: "Lorem ipsum")
    # user.microposts.create!() 
    #   userに紐付いたマイクロポストを作成する
    assert_difference 'Micropost.count', -1 do
    # 削除されてマイクロポストの数が一つ減っているかどうか？
      @user.destroy
      # ユーザーを削除
    end
  end
end
```
#####テスト
```
ubuntu:~/environment/sample_app (user-microposts) $ rails t
Running via Spring preloader in process 8038
Started with run options --seed 14565

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

Finished in 4.22841s
53 tests, 221 assertions, 0 failures, 0 errors, 0 skips
```
###演習
1.
Micropost.first.created_atの実行結果と、Micropost.last.created_atの実行結果を比べてみましょう。

```rb
>> Micropost.first.created_at
   (1.5ms)  SELECT sqlite_version(*)
  Micropost Load (0.8ms)  SELECT "microposts".* FROM "microposts" ORDER BY "microposts"."created_at" DESC LIMIT ?  [["LIMIT", 1]]
=> Fri, 22 Oct 2021 13:59:35 UTC +00:00

>> Micropost.last.created_at
  Micropost Load (0.2ms)  SELECT "microposts".* FROM "microposts" ORDER BY "microposts"."created_at" ASC LIMIT ?  [["LIMIT", 1]]
=> Fri, 22 Oct 2021 06:31:48 UTC +00:00
```
時間が違う。

2.
Micropost.firstを実行したときに発行されるSQL文はどうなっているでしょうか? 同様にして、Micropost.lastの場合はどうなっているでしょうか? ヒント: それぞれをコンソール上で実行したときに表示される文字列が、SQL文になります。

```rb
>> Micropost.first
  Micropost Load (0.2ms)  SELECT "microposts".* FROM "microposts" ORDER BY "microposts"."created_at" DESC LIMIT ?  [["LIMIT", 1]]
=> #<Micropost id: 3, content: "Lorem ipsum", user_id: 1, created_at: "2021-10-22 13:59:35", updated_at: "2021-10-22 13:59:35">

>> Micropost.last
  Micropost Load (0.2ms)  SELECT "microposts".* FROM "microposts" ORDER BY "microposts"."created_at" ASC LIMIT ?  [["LIMIT", 1]]
=> #<Micropost id: 1, content: "Lerem ipsum", user_id: 1, created_at: "2021-10-22 06:31:48", updated_at: "2021-10-22 06:31:48">
```
.firstが降順 .lastが昇順になっている。

3.
データベース上の最初のユーザーを変数userに代入してください。そのuserオブジェクトが最初に投稿したマイクロポストのidはいくつでしょうか? 次に、destroyメソッドを使ってそのuserオブジェクトを削除してみてください。削除すると、そのuserに紐付いていたマイクロポストも削除されていることをMicropost.findで確認してみましょう。

```rb
>> user.microposts
  Micropost Load (1.0ms)  SELECT "microposts".* FROM "microposts" WHERE "microposts"."user_id" = ? ORDER BY "microposts"."created_at" DESC LIMIT ?  [["user_id", 1], ["LIMIT", 11]]
=> #<ActiveRecord::Associations::CollectionProxy [#<Micropost id: 3, content: "Lorem ipsum", user_id: 1, created_at: "2021-10-22 13:59:35", updated_at: "2021-10-22 13:59:35">, #<Micropost id: 2, content: "Lorem ipsum", user_id: 1, created_at: "2021-10-22 13:53:49", updated_at: "2021-10-22 13:53:49">, #<Micropost id: 1, content: "Lerem ipsum", user_id: 1, created_at: "2021-10-22 06:31:48", updated_at: "2021-10-22 06:31:48">]>

>> user.destroy
   (0.1ms)  begin transaction
  Micropost Load (0.2ms)  SELECT "microposts".* FROM "microposts" WHERE "microposts"."user_id" = ? ORDER BY "microposts"."created_at" DESC  [["user_id", 1]]
  Micropost Destroy (2.3ms)  DELETE FROM "microposts" WHERE "microposts"."id" = ?  [["id", 3]]
  Micropost Destroy (0.1ms)  DELETE FROM "microposts" WHERE "microposts"."id" = ?  [["id", 2]]
  Micropost Destroy (0.1ms)  DELETE FROM "microposts" WHERE "microposts"."id" = ?  [["id", 1]]
  User Destroy (0.7ms)  DELETE FROM "users" WHERE "users"."id" = ?  [["id", 1]]
   (7.4ms)  commit transaction
=> #<User id: 1, name: "Example User", email: "example@railstutorial.org", created_at: "2021-10-17 05:28:48", updated_at: "2021-10-20 14:25:39", password_digest: [FILTERED], remember_digest: nil, admin: true, activation_digest: "$2a$12$x4xVHmtrDFjVPFFWav31UebLY8r9sdT8ImzSXGSrnqt...", activated: true, activated_at: "2021-10-17 05:28:48", reset_digest: "$2a$12$FhfOA3Y7VPJ3TJJ5nNUEkuSH0hkGrrW15uyYE9EwbrC...", reset_sent_at: "2021-10-20 14:25:39">

>> Micropost.find
Traceback (most recent call last):
        1: from (irb):15
ActiveRecord::RecordNotFound (Couldn't find Micropost without an ID)
```

###困ったこと
example_Userを削除してしまった。
調べて
```rails db:migrate:reset```
```rails db:seed ```
をして治った。