0
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チュートリアル第13章 マイクロポストを改良する

Posted at

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

####マイクロポストの順序付けをテストする
test/models/micropost_test.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

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 }
  # 最大140文字まで
end
>> -> {puts "foo" }
=> #<Proc:0x000055622fc512c8@(irb):1 (lambda)>
>> -> {puts "foo" }.call
foo
=> nil

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

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

####dependent: :destroyのテスト
test/models/user_test.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の実行結果を比べてみましょう。

>> 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

時間が違う。

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

>> 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が昇順になっている。

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

>> 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
をして治った。

0
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
0
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?