13.1.1
演習
RailsコンソールでMicropost.newを実行し、インスタンスを変数micropostに代入してください。その後、user_idに最初のユーザーのidを、contentに "Lorem ipsum" をそれぞれ代入してみてください。この時点では、 micropostオブジェクトのマジックカラム (created_atとupdated_at) には何が入っているでしょうか?
先ほど作ったオブジェクトを使って、micropost.userを実行してみましょう。どのような結果が返ってくるでしょうか? また、micropost.user.nameを実行した場合の結果はどうなるでしょうか?
先ほど作ったmicropostオブジェクトをデータベースに保存してみましょう。この時点でもう一度マジックカラムの内容を調べてみましょう。今度はどのような値が入っているでしょうか?
1
>> micropost = Micropost.new
=> #<Micropost id: nil, content: nil, user_id: nil, created_at: nil, updated_at: nil>
>> micropost.user_id = User.first.id
User Load (0.2ms) SELECT "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT ? [["LIMIT", 1]]
=> 1
>> micropost.content = "Lorem ipsum"
=> "Lorem ipsum"
>> micropost.created_at
=> nil
>> micropost.updated_at
=> nil
>
2
>> micropost.user
User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ? [["id", 1], ["LIMIT", 1]]
=> #<User id: 1, name: "Example User", email: "example@railstutorial.org", created_at: "2019-04-21 11:43:41", updated_at: "2019-05-04 11:47:38", password_digest: "$2a$10$0J3/6mpDJ2x8vFb2OdNBZOskHIcpGnaLjbkh0eI9Yzu...", remember_digest: nil, admin: true, activation_digest: "$2a$10$JDqeO5RqJf.oRt1Uly.SGelGym2U6Emi4AUU.ErmhZU...", activated: true, activated_at: "2019-04-21 11:43:40", reset_digest: "$2a$10$beh3nZlvKzWaUaqcGRjyfuH2A6bpT4irIhpZGuD4rI6...", reset_sent_at: "2019-05-04 11:42:31">
>> micropost.user.name
=> "Example User"
3
>> micropost.save
(0.1ms) begin transaction
SQL (2.1ms) INSERT INTO "microposts" ("content", "user_id", "created_at", "updated_at") VALUES (?, ?, ?, ?) [["content", "Lorem ipsum"], ["user_id", 1], ["created_at", "2019-05-06 11:17:52.944180"], ["updated_at", "2019-05-06 11:17:52.944180"]]
(6.0ms) commit transaction
=> true
>> micropost.created_at
=> Mon, 06 May 2019 11:17:52 UTC +00:00
>> micropost.updated_at
=> Mon, 06 May 2019 11:17:52 UTC +00:00
13.1.2
演習
Railsコンソールを開き、user_idとcontentが空になっているmicropostオブジェクトを作ってみてください。このオブジェクトに対してvalid?を実行すると、失敗することを確認してみましょう。また、生成されたエラーメッセージにはどんな内容が書かれているでしょうか?
コンソールを開き、今度はuser_idが空でcontentが141文字以上のmicropostオブジェクトを作ってみてください。このオブジェクトに対してvalid?を実行すると、失敗することを確認してみましょう。また、生成されたエラーメッセージにはどんな内容が書かれているでしょうか?
1
>> micropost =Micropost.new(user_id: "",content: "")
=> #<Micropost id: nil, content: "", user_id: nil, created_at: nil, updated_at: nil>
>> micropost.valid?
=> false
>> micropost.errors.full_messages
=> ["User must exist", "User can't be blank", "Content can't be blank"]
>>
2
>> micropost =Micropost.new(user_id: "",content: "a" * 141)
=> #<Micropost id: nil, content: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa...", user_id: nil, created_at: nil, updated_at: nil>
>> micropost.valid?=> false
>> micropost.errors.full_messages=> ["User must exist", "User can't be blank", "Content is too long (maximum is 140 characters)"]
>>
13.1.3
演習
データベースにいる最初のユーザーを変数userに代入してください。そのuserオブジェクトを使ってmicropost = user.microposts.create(content: "Lorem ipsum")を実行すると、どのような結果が得られるでしょうか?
先ほどの演習課題で、データベース上に新しいマイクロポストが追加されたはずです。user.microposts.find(micropost.id)を実行して、本当に追加されたのかを確かめてみましょう。また、先ほど実行したmicropost.idの部分をmicropostに変更すると、結果はどうなるでしょうか?
user == micropost.userを実行した結果はどうなるでしょうか? また、user.microposts.first == micropost を実行した結果はどうなるでしょうか? それぞれ確認してみてください。
1
>> user= User.first
User Load (0.2ms) SELECT "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT ? [["LIMIT", 1]]
=> #<User id: 1, name: "Example User", email: "example@railstutorial.org", created_at: "2019-04-21 11:43:41", updated_at: "2019-05-04 11:47:38", password_digest: "$2a$10$0J3/6mpDJ2x8vFb2OdNBZOskHIcpGnaLjbkh0eI9Yzu...", remember_digest: nil, admin: true, activation_digest: "$2a$10$JDqeO5RqJf.oRt1Uly.SGelGym2U6Emi4AUU.ErmhZU...", activated: true, activated_at: "2019-04-21 11:43:40", reset_digest: "$2a$10$beh3nZlvKzWaUaqcGRjyfuH2A6bpT4irIhpZGuD4rI6...", reset_sent_at: "2019-05-04 11:42:31">
>> micropost = user.microposts.create(content: "Lorem ipsum")
(0.1ms) begin transaction
SQL (5.5ms) INSERT INTO "microposts" ("content", "user_id", "created_at", "updated_at") VALUES (?, ?, ?, ?) [["content", "Lorem ipsum"], ["user_id", 1], ["created_at", "2019-05-07 02:03:41.026572"], ["updated_at", "2019-05-07 02:03:41.026572"]]
(5.3ms) commit transaction
=> #<Micropost id: 2, content: "Lorem ipsum", user_id: 1, created_at: "2019-05-07 02:03:41", updated_at: "2019-05-07 02:03:41">
2
>> user.microposts.find(2)
Micropost Load (0.2ms) SELECT "microposts".* FROM "microposts" WHERE "microposts"."user_id" = ? AND "microposts"."id" = ? LIMIT ? [["user_id", 1], ["id", 2], ["LIMIT", 1]]
=> #<Micropost id: 2, content: "Lorem ipsum", user_id: 1, created_at: "2019-05-07 02:03:41", updated_at: "2019-05-07 02:03:41">
3
>> user == micropost.user
=> true
>> user.microposts.first == micropost
Micropost Load (0.6ms) SELECT "microposts".* FROM "microposts" WHERE "microposts"."user_id" = ? ORDER BY "microposts"."id" ASC LIMIT ? [["user_id", 1], ["LIMIT", 1]]
=> false
13.1.4
演習
Micropost.first.created_atの実行結果と、Micropost.last.created_atの実行結果を比べてみましょう。
Micropost.firstを実行したときに発行されるSQL文はどうなっているでしょうか? 同様にして、Micropost.lastの場合はどうなっているでしょうか? ヒント: それぞれをコンソール上で実行したときに表示される文字列が、SQL文になります。
データベース上の最初のユーザーを変数userに代入してください。そのuserオブジェクトが最初に投稿したマイクロポストのidはいくつでしょうか? 次に、destroyメソッドを使ってそのuserオブジェクトを削除してみてください。削除すると、そのuserに紐付いていたマイクロポストも削除されていることをMicropost.findで確認してみましょう。
1
>> Micropost.first.created_at
Micropost Load (1.3ms) SELECT "microposts".* FROM "microposts" ORDER BY "microposts"."created_at" DESC LIMIT ? [["LIMIT", 1]]
=> Tue, 07 May 2019 02:03:41 UTC +00:00
>> Micropost.last.created_at
Micropost Load (0.3ms) SELECT "microposts".* FROM "microposts" ORDER BY "microposts"."created_at" ASC LIMIT ? [["LIMIT", 1]]
=> Mon, 06 May 2019 11:17:52 UTC +00:00
>>
2
>> Micropost.first
Micropost Load (0.1ms) SELECT "microposts".* FROM "microposts" ORDER BY "microposts"."created_at" DESC LIMIT ? [["LIMIT", 1]]
=> #<Micropost id: 2, content: "Lorem ipsum", user_id: 1, created_at: "2019-05-07 02:03:41", updated_at: "2019-05-07 02:03:41">
>> Micropost.last
Micropost Load (0.2ms) SELECT "microposts".* FROM "microposts" ORDER BY "microposts"."created_at" ASC LIMIT ? [["LIMIT", 1]]
=> #<Micropost id: 1, content: "Lorem ipsum", user_id: 1, created_at: "2019-05-06 11:17:52", updated_at: "2019-05-06 11:17:52">
DESC LIMITとASC LIMITでそれぞれソートしている
3
>> user = User.first
User Load (0.2ms) SELECT "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT ? [["LIMIT", 1]]
=> #<User id: 1, name: "Example User", email: "example@railstutorial.org", created_at: "2019-04-21 11:43:41", updated_at: "2019-05-04 11:47:38", password_digest: "$2a$10$0J3/6mpDJ2x8vFb2OdNBZOskHIcpGnaLjbkh0eI9Yzu...", remember_digest: nil, admin: true, activation_digest: "$2a$10$JDqeO5RqJf.oRt1Uly.SGelGym2U6Emi4AUU.ErmhZU...", activated: true, activated_at: "2019-04-21 11:43:40", reset_digest: "$2a$10$beh3nZlvKzWaUaqcGRjyfuH2A6bpT4irIhpZGuD4rI6...", reset_sent_at: "2019-05-04 11:42:31">
>> user.microposts.find_by(id: 1)
Micropost Load (0.2ms) SELECT "microposts".* FROM "microposts" WHERE "microposts"."user_id" = ? AND "microposts"."id" = ? ORDER BY "microposts"."created_at" DESC LIMIT ? [["user_id", 1], ["id", 1], ["LIMIT", 1]]
=> #<Micropost id: 1, content: "Lorem ipsum", user_id: 1, created_at: "2019-05-06 11:17:52", updated_at: "2019-05-06 11:17:52">
>> 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]]
SQL (2.1ms) DELETE FROM "microposts" WHERE "microposts"."id" = ? [["id", 2]]
SQL (0.1ms) DELETE FROM "microposts" WHERE "microposts"."id" = ? [["id", 1]]
SQL (0.5ms) DELETE FROM "users" WHERE "users"."id" = ? [["id", 1]]
(7.4ms) commit transaction
=> #<User id: 1, name: "Example User", email: "example@railstutorial.org", created_at: "2019-04-21 11:43:41", updated_at: "2019-05-04 11:47:38", password_digest: "$2a$10$0J3/6mpDJ2x8vFb2OdNBZOskHIcpGnaLjbkh0eI9Yzu...", remember_digest: nil, admin: true, activation_digest: "$2a$10$JDqeO5RqJf.oRt1Uly.SGelGym2U6Emi4AUU.ErmhZU...", activated: true, activated_at: "2019-04-21 11:43:40", reset_digest: "$2a$10$beh3nZlvKzWaUaqcGRjyfuH2A6bpT4irIhpZGuD4rI6...", reset_sent_at: "2019-05-04 11:42:31">
>> Micropost.find(1)
Micropost Load (1.1ms) SELECT "microposts".* FROM "microposts" WHERE "microposts"."id" = ? ORDER BY "microposts"."created_at" DESC LIMIT ? [["id", 1], ["LIMIT", 1]]
Traceback (most recent call last):
1: from (irb):8
ActiveRecord::RecordNotFound (Couldn't find Micropost with 'id'=1)
>>
13.2.1
演習
7.3.3で軽く説明したように、今回ヘルパーメソッドとして使ったtime_ago_in_wordsメソッドは、Railsコンソールのhelperオブジェクトから呼び出すことができます。このhelperオブジェクトのtime_ago_in_wordsメソッドを使って、3.weeks.agoや6.months.agoを実行してみましょう。
helper.time_ago_in_words(1.year.ago)と実行すると、どういった結果が返ってくるでしょうか?
micropostsオブジェクトのクラスは何でしょうか? ヒント: リスト 13.23内のコードにあるように、まずはpaginateメソッド (引数はpage: nil) でオブジェクトを取得し、その後classメソッドを呼び出してみましょう。
1,2
>> helper.time_ago_in_words(3.weeks.ago)
=> "21 days"
>> helper.time_ago_in_words(6.months.ago)
=> "6 months"
>> helper.time_ago_in_words(1.year.ago)
=> "about 1 year"
3
>> user = User.first
User Load (0.2ms) SELECT "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT ? [["LIMIT", 1]]
=> #<User id: 1, name: "Example User", email: "example@railstutorial.org", created_at: "2019-05-07 05:47:25", updated_at: "2019-05-07 05:47:25", password_digest: "$2a$10$QRkKx2KrqTkrHRMLVH.e5egPoaBdgtwmXQ6WGa1U1jF...", remember_digest: nil, admin: true, activation_digest: "$2a$10$NesRhlkJ.qhEx4jne8HfduqzO8zqxa611pyZQq76/2M...", activated: true, activated_at: "2019-05-07 05:47:25", reset_digest: nil, reset_sent_at: nil>
>> microposts = user.microposts.paginate(page: nil)
Micropost Load (0.2ms) SELECT "microposts".* FROM "microposts" WHERE "microposts"."user_id" = ? ORDER BY "microposts"."created_at" DESC LIMIT ? OFFSET ? [["user_id", 1], ["LIMIT", 11], ["OFFSET", 0]]
=> #<ActiveRecord::AssociationRelation []>
>> microposts.class
=> Micropost::ActiveRecord_AssociationRelation
>>
13.2.2
演習
(1..10).to_a.take(6)というコードの実行結果を推測できますか? 推測した値が合っているかどうか、実際にコンソールを使って確認してみましょう。
先ほどの演習にあったto_aメソッドの部分は本当に必要でしょうか? 確かめてみてください。
Fakerはlorem ipsum以外にも、非常に多種多様の事例に対応しています。Fakerのドキュメント (英語) を眺めながら画面に出力する方法を学び、実際に大学名や電話番号、Hipster IpsumやChuck Norris facts (参考: チャック・ノリスの真実) を画面に出力してみましょう。(訳注: もちろん日本語にも対応していて、例えば沖縄らしい用語を出力するfaker-okinawaもあります。ぜひ遊んでみてください。)
1
>> (1..10).to_a.take(6)
=> [1, 2, 3, 4, 5, 6]
2
>> (1..10).take(6)
=> [1, 2, 3, 4, 5, 6]
13.2.2
演習
- リスト 13.28にある2つの’h1’のテストが正しいか確かめるため、該当するアプリケーション側のコードをコメントアウトしてみましょう。テストが green から redに変わることを確認してみてください。
- リスト 13.28にあるテストを変更して、will_paginateが1度のみ表示されていることをテストしてみましょう。ヒント: 表 5.2を参考にしてください。
1
確認
2
assert_select 'div.pagination', count: 1
13.3.1
演習
1
なぜUsersコントローラ内にあるlogged_in_userフィルターを残したままにするとマズイのでしょうか? 考えてみてください。
1同じメソッドが重複して予期せぬ挙動の原因になるから
13.3.2
演習
- Homeページをリファクタリングして、if-else文の分岐のそれぞれに対してパーシャルを作ってみましょう。
元の
<% if logged_in? %>
<div class="row">
<aside class="col-md-4">
<section class="user_info">
<%= render 'shared/user_info' %>
</section>
<section class="micropost_form">
<%= render 'shared/micropost_form' %>
</section>
</aside>
</div>
<% else %>
<div class="center jumbotron">
<h1>Welcome to the Sample App</h1>
<h2>
This is the home page for the
<a href="https://railstutorial.jp/">Ruby on Rails Tutorial</a>
sample application.
</h2>
<%= link_to "Sign up now!", signup_path, class: "btn btn-lg btn-primary" %>
</div>
<%= link_to image_tag("rails.png", alt: "Rails logo"),
'http://rubyonrails.org/' %>
<% end %>
<% if logged_in? %>
<%= render 'static_pages/_logged_in'%>
<% else %>
<%= render 'static_pages/_not_logged_in'%>
<% end %>
<div class="row">
<aside class="col-md-4">
<section class="user_info">
<%= render 'shared/user_info' %>
</section>
<section class="micropost_form">
<%= render 'shared/micropost_form' %>
</section>
</aside>
</div>
<div class="center jumbotron">
<h1>Welcome to the Sample App</h1>
<h2>
This is the home page for the
<a href="https://railstutorial.jp/">Ruby on Rails Tutorial</a>
sample application.
</h2>
<%= link_to "Sign up now!", signup_path, class: "btn btn-lg btn-primary" %>
</div>
<%= link_to image_tag("rails.png", alt: "Rails logo"),
'http://rubyonrails.org/' %>
13.3.3.
演習
- 新しく実装したマイクロポストの投稿フォームを使って、実際にマイクロポストを投稿してみましょう。Railsサーバーのログ内にあるINSERT文では、どういった内容をデータベースに送っているでしょうか? 確認してみてください。
- コンソールを開き、user変数にデータベース上の最初のユーザーを代入してみましょう。その後、Micropost.where("user_id = ?", user.id)とuser.microposts、そしてuser.feedをそれぞれ実行してみて、実行結果がすべて同じであることを確認してみてください。ヒント: ==で比較すると結果が同じかどうか簡単に判別できます。
1
>{"content"=>"123456testtest"}, "commit"=>"Post"}
User Load (0.6ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ? [["id", 1], ["LIMIT", 1]]
(0.0ms) begin transaction
SQL (4.1ms) INSERT INTO "microposts" ("content", "user_id", "created_at", "updated_at") VALUES (?, ?, ?, ?) [["content", "123456testtest"], ["user_id", 1], ["created_at", "2019-05-08 05:30:37.728696"], ["updated_at", "2019-05-08 05:30:37.728696"]]
(6.5ms) commit transaction
2
>> user = User.first
>> Micropost.where("user_id = ?", user.id) == user.microposts
Micropost Load (367.6ms) SELECT "microposts".* FROM "microposts" WHERE "microposts"."user_id" = ? ORDER BY "microposts"."created_at" DESC [["user_id", 1]]
Micropost Load (19.2ms) SELECT "microposts".* FROM "microposts" WHERE (user_id = 1) ORDER BY "microposts"."created_at" DESC
=> true
>> Micropost.where("user_id = ?", user.id) == user.feed
=> true
>> user.microposts == user.feed
Micropost Load (20.8ms) SELECT "microposts".* FROM "microposts" WHERE (user_id = 1) ORDER BY "microposts"."created_at" DESC
=> true
13.3.5演習
- リスト 13.55で示した4つのコメント (「無効な送信」など) のそれぞれに対して、テストが正しく動いているか確認してみましょう。具体的には、対応するアプリケーション側のコードをコメントアウトし、テストが redになることを確認し、元に戻すと greenになることを確認してみましょう。
- サイドバーにあるマイクロポストの合計投稿数をテストしてみましょう。このとき、単数形 (micropost) と複数形 (microposts) が正しく表示されているかどうかもテストしてください。ヒント: リスト 13.57を参考にしてみてください。
1
無効なマイクロポストを投稿、有効なマイクロポストを投稿、マイクロポストの削除、そして他のユーザーのマイクロポストには [delete] リンクが表示されないことを確認、
無効な送信
def create
@micropost = current_user.microposts.build(micropost_params)
if @micropost.save
flash[:success] = "Micropost created!"
redirect_to root_url
else
@feed_items = []
render 'static_pages/home'
end
end
をコメントアウトすると
ERROR["test_should_redirect_create_when_not_logged_in", MicropostsControllerTest, 1.996017354002106]
test_should_redirect_create_when_not_logged_in#MicropostsControllerTest (2.00s)
AbstractController::ActionNotFound: AbstractController::ActionNotFound: The action 'create' could not be found for MicropostsController
test/controllers/microposts_controller_test.rb:11:in `block (2 levels) in <class:MicropostsControllerTest>'
test/controllers/microposts_controller_test.rb:10:in `block in <class:MicropostsControllerTest>'
ERROR["test_micropost_interface", MicropostsInterfaceTest, 2.111486043999321]
test_micropost_interface#MicropostsInterfaceTest (2.11s)
AbstractController::ActionNotFound: AbstractController::ActionNotFound: The action 'create' could not be found for MicropostsController
test/integration/microposts_interface_test.rb:15:in `block (2 levels) in <class:MicropostsInterfaceTest>'
test/integration/microposts_interface_test.rb:14:in `block in <class:MicropostsInterfaceTest>'
est_should_redirect_create_when_not_logged_inも一緒にテストではじかれてしまったがこの部分であっている?
投稿を削除するのテストは以下をコメントアウトすると
def destroy
@micropost.destroy
flash[:success] = "Micropost deleted"
redirect_back(fallback_location: root_url)
end
結果
ERROR["test_should_redirect_destroy_for_wrong_micropost", MicropostsControllerTest, 1.2442943940041005]
test_should_redirect_destroy_for_wrong_micropost#MicropostsControllerTest (1.24s)
AbstractController::ActionNotFound: AbstractController::ActionNotFound: The action 'destroy' could not be found for MicropostsController
test/controllers/microposts_controller_test.rb:27:in `block (2 levels) in <class:MicropostsControllerTest>'
test/controllers/microposts_controller_test.rb:26:in `block in <class:MicropostsControllerTest>'
ERROR["test_should_redirect_destroy_when_not_logged_in", MicropostsControllerTest, 1.2528192390018376]
test_should_redirect_destroy_when_not_logged_in#MicropostsControllerTest (1.25s)
AbstractController::ActionNotFound: AbstractController::ActionNotFound: The action 'destroy' could not be found for MicropostsController
test/controllers/microposts_controller_test.rb:18:in `block (2 levels) in <class:MicropostsControllerTest>'
test/controllers/microposts_controller_test.rb:17:in `block in <class:MicropostsControllerTest>'
ERROR["test_micropost_interface", MicropostsInterfaceTest, 1.9133356579986867]
test_micropost_interface#MicropostsInterfaceTest (1.91s)
AbstractController::ActionNotFound: AbstractController::ActionNotFound: The action 'destroy' could not be found for MicropostsController
test/integration/microposts_interface_test.rb:30:in `block (2 levels) in <class:MicropostsInterfaceTest>'
test/integration/microposts_interface_test.rb:29:in `block in <class:MicropostsInterfaceTest>'
55/55: [==========] 100% Time: 00:00:02, Time: 00:00:02
Finished in 2.21534s
55 tests, 288 assertions, 0 failures, 3 errors, 0 skips
3つもエラーがでるのでやりすぎらしい
@micropost.destroyだけをコメントアウトすると
FAIL["test_micropost_interface", MicropostsInterfaceTest, 2.2194056610023836]
test_micropost_interface#MicropostsInterfaceTest (2.22s)
"Micropost.count" didn't change by -1.
Expected: 38
Actual: 39
test/integration/microposts_interface_test.rb:29:in `block in <class:MicropostsInterfaceTest>'
55/55: [==========] 100% Time: 00:00:02, Time: 00:00:02
Finished in 2.24183s
55 tests, 293 assertions, 1 failures, 0 errors, 0 skips
これで
assert_difference 'Micropost.count', -1 doの部分がうまくいっていると確認?
def create内の
@feed_items = []をコメントアウトして無効な送信テストの確認
結果
ERROR["test_micropost_interface", MicropostsInterfaceTest, 2.127671581998584]
test_micropost_interface#MicropostsInterfaceTest (2.13s)
ActionView::Template::Error: ActionView::Template::Error: undefined method `any?' for nil:NilClass
app/views/shared/_feed.html.erb:1:in `_app_views_shared__feed_html_erb___2635249087422250435_66072860'
app/views/static_pages/_logged_in.html.erb:12:in `_app_views_static_pages__logged_in_html_erb__2347269424197631278_65986000'
app/views/static_pages/home.html.erb:2:in `_app_views_static_pages_home_html_erb__234919273053642744_70042497772920'
app/controllers/microposts_controller.rb:12:in `create'
test/integration/microposts_interface_test.rb:15:in `block (2 levels) in <class:MicropostsInterfaceTest>'
test/integration/microposts_interface_test.rb:14:in `block in <class:MicropostsInterfaceTest>'
55/55: [==========] 100% Time: 00:00:02, Time: 00:00:02
Finished in 2.13492s
55 tests, 285 assertions, 0 failures, 1 errors, 0 skips
2
test "micropost sidebar count" do
log_in_as(@user)
get root_path
assert_match "#{@user.microposts.count} microposts", response.body
# まだマイクロポストを投稿していないユーザー
other_user = users(:malory)
log_in_as(other_user)
get root_path
assert_match "0 microposts", response.body
other_user.microposts.create!(content: "A micropost")
get root_path
assert_match "1 micropost", response.body
End
13.4.1
演習
画像付きのマイクロポストを投稿してみましょう。もしかして、大きすぎる画像が表示されてしまいましたか? (心配しないでください、次の13.4.3でこの問題を直します)。
リスト 13.63に示すテンプレートを参考に、13.4で実装した画像アップローダーをテストしてください。テストの準備として、まずはサンプル画像をfixtureディレクトリに追加してください (コマンド例: cp app/assets/images/rails.png test/fixtures/)。リスト 13.63で追加したテストでは、Homeページにあるファイルアップロードと、投稿に成功した時に画像が表示されているかどうかをチェックしています。なお、テスト内にあるfixture_file_uploadというメソッドは、fixtureで定義されたファイルをアップロードする特別なメソッドです18。ヒント: picture属性が有効かどうかを確かめるときは、11.3.3で紹介したassignsメソッドを使ってください。このメソッドを使うと、投稿に成功した後にcreateアクション内のマイクロポストにアクセスするようになります。
1
確認
2
test "micropost interface" do
log_in_as(@user)
get root_path
assert_select 'div.pagination'
assert_select 'input[type=file]'
# 無効な送信
assert_no_difference 'Micropost.count' do
post microposts_path, params: { micropost: { content: "" } }
end
assert_select 'div#error_explanation'
# 有効な送信
content = "This micropost really ties the room together"
picture = fixture_file_upload('test/fixtures/rails.png', 'image/png')
assert_difference 'Micropost.count', 1 do
post microposts_path, params: { micropost:
{ content: content,
picture: picture } }
end
assert assigns(:micropost).picture?
follow_redirect!
assert_match content, response.body
# 投稿を削除する
assert_select "a", text: 'delete'
first_micropost = @user.microposts.paginate(page: 1).first
assert_difference 'Micropost.count', -1 do
delete micropost_path(first_micropost)
end
get user_path(users(:archer))
assert_select 'a', text: "delete", count: 0
end
13.4.2
演習
5MB以上の画像ファイルを送信しようとした場合、どうなりますか?
無効な拡張子のファイルを送信しようとした場合、どうなりますか?
2
エラーが出る