1
1

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 1 year has passed since last update.

Rails tutorial 第13章

Posted at

演習1

RailsコンソールでMicropost.newを実行し、インスタンスを変数micropostに代入してください。その後、user_idに最初のユーザーのidを、contentに "Lorem ipsum" をそれぞれ代入してみてください。この時点では、 micropostオブジェクトのマジックカラムであるcreated_atとupdated_atには何が入っているでしょうか?

指示通りにやってみると、nilとなります

 micropost = Micropost.new
=> #<Micropost:0x00007fd6b50cfe98 id: nil, content: nil, user_id: nil, created_at: nil, updated_at: nil>
irb(main):002:0> micropost.user_id = User.first.id
  User Load (0.2ms)  SELECT "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT ?  [["LIMIT", 1]]
=> 1
irb(main):003:0> micropost.content = "Lorem ipsum"
=> "Lorem ipsum"
irb(main):004:0> micropost.created_at
=> nil
irb(main):005:0> micropost.updated_at
=> nil

先ほど作ったオブジェクトを使って、micropost.userを実行してみましょう。どのような結果が返ってくるでしょうか? また、micropost.user.nameを実行した場合の結果はどうなるでしょうか?

micropost.user
  User Load (0.2ms)  SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ?  [["id", 1], ["LIMIT", 1]]
=> 
#<User:0x00007fd6b4e0b630
 id: 1,
 name: "Example User",
 email: "example@railstutorial.org",
 created_at: Sun, 01 Oct 2023 08:28:59.861078000 UTC +00:00,
 updated_at: Tue, 03 Oct 2023 20:58:27.716591000 UTC +00:00,
 password_digest: "$2a$12$0bjsfJOdgTsq9bBRNTJFbu7.Z7LEPIoz4Q8KJIjcxX9UOOu5LcK2a",
 remember_digest: "$2a$12$T159OCf/5y10RMmQb8zCH.KLUna7G3CJFpbnJn1zr73jcNk8OKA.C",
 admin: true,
 activation_digest: "$2a$12$pkJnv9FWgk753jd0oPM4TeV7y4P2q7fZNgfTXZH.D.ATGhwZrAnz2",
 activated: true,
 activated_at: Sun, 01 Oct 2023 08:28:59.606888000 UTC +00:00,
 reset_digest: "$2a$12$O6oFLkLe8Cc81C0VCQPi2.sDODGvr801KmgmZ0G/AgSffQ1xz6FqO",
 reset_sent_at: Tue, 03 Oct 2023 20:58:27.716286000 UTC +00:00>

 micropost.user.name
=> "Example User"

先ほど作ったmicropostオブジェクトをデータベースに保存してみましょう。この時点でもう一度マジックカラムの内容を調べてみましょう。今度はどのような値が入っているでしょうか?

データベースに保存されると、更新日時などが示されました

> micropost.save
  TRANSACTION (0.1ms)  begin transaction
  Micropost Create (0.5ms)  INSERT INTO "microposts" ("content", "user_id", "created_at", "updated_at") VALUES (?, ?, ?, ?)  [["content", "Lorem ipsum"], ["user
micropost.created_at
=> Sun, 08 Oct 2023 07:00:16.111795000 UTC +00:00
irb(main):014:0> micropost.updated_at
=> Sun, 08 Oct 2023 07:00:16.111795000 UTC +00:00

演習2

Railsコンソールを開き、user_idとcontentが空になっているmicropostオブジェクトを作ってみてください。このオブジェクトに対してvalid?を実行すると、失敗することを確認してみましょう。また、生成されたエラーメッセージにはどんな内容が書かれているでしょうか?

ropost
irb(main):004:0> micropost = Micropost.new
=> #<Micropost:0x00007f191cb0d358 id: nil, content: nil, user_id: nil, created_at: nil, updated_at: nil>
irb(main):005:0> micropost.valid?
=> false
 micropost.errors.full_messages
=> ["User must exist", "User can't be blank", "Content can't be blank"]

コンソールを開き、今度はuser_idが空でcontentが141文字以上のmicropostオブジェクトを作ってみてください。このオブジェクトに対してvalid?を実行すると、失敗することを確認してみましょう。また、生成されたエラーメッセージにはどんな内容が書かれているでしょうか?

上記の演習からそのまま続行しています

 micropost.content = "a"*141
=> "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
irb(main):011:0> micropost.valid?
=> false
irb(main):012:0> micropost.errors.full_messages
=> ["User must exist", "User can't be blank", "Content is too long (maximum is 140 characters)"]

演習3

データベースにいる最初のユーザーを変数userに代入してください。そのuserオブジェクトを使ってmicropost = user.microposts.create(content: "Lorem ipsum")を実行すると、どのような結果が得られるでしょうか?

前回のマイクロポストを残してしまっていますが、そのまま載せています

 user = User.first
  User Load (5.8ms)  SELECT "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT ?  [["LIMIT", 1]]
=> 
#<User:0x00007fc9406b3350
...
irb(main):002:0> micropost = user.microposts.create(content: "Lorem ipsum")
  TRANSACTION (0.1ms)  begin transaction
  Micropost Create (12.3ms)  INSERT INTO "microposts" ("content", "user_id", "created_at", "updated_at") VALUES (?, ?, ?, ?)  [["content", "Lorem ipsum"], ["user_id", 1], ["created_at", "2023-10-08 21:37:34.533382"], ["updated_at", "2023-10-08 21:37:34.533382"]]
  TRANSACTION (31.2ms)  commit transaction

先ほどの演習課題で、データベース上に新しいマイクロポストが追加されたはずです。user.microposts.find(micropost.id)を実行して、本当に追加されたのかを確かめてみましょう。また、先ほど実行したmicropost.idの部分をmicropostに変更すると、結果はどうなるでしょうか?

user.microposts.find(micropost.id)
  Micropost Load (0.2ms)  SELECT "microposts".* FROM "microposts" WHERE "microposts"."user_id" = ? AND "microposts"."id" = ? LIMIT ?  [["user_id", 1], ["id", 2], ["LIMIT", 1]]
=> 
#<Micropost:0x00007fc9413d26d0
 id: 2,
 content: "Lorem ipsum",
 user_id: 1,
 created_at: Sun, 08 Oct 2023 21:37:34.533382000 UTC +00:00,
 updated_at: Sun, 08 Oct 2023 21:37:34.533382000 UTC +00:00>
irb(main):005:0> user.microposts.find(micropost)
/usr/local/rvm/gems/default/gems/activerecord-7.0.4.3/lib/active_record/relation/finder_methods.rb:466:in `find_one': You are passing an instance of ActiveRecord::Base to `find`. Please pass the id of the object by calling `.id`. (ArgumentError)

          raise ArgumentError, <<-MSG.squish

micropostにするとエラーになるようです。これはrails5.1から警告からエラーになるように変わったようです
まあ、かならずfindを使用する場合にはidを付けてあげましょうということですね

user == micropost.userを実行した結果はどうなるでしょうか? また、user.microposts.first == micropost を実行した結果はどうなるでしょうか? それぞれ確認してみてください。

irb(main):006:0> user == micropost.user
=> true
irb(main):007:0> user.microposts.first == micropost
=> false

演習4

Micropost.first.created_atの実行結果と、Micropost.last.created_atの実行結果を比べてみましょう。

最初の投稿と最後の投稿で時間帯が異なることを確認します

Micropost.first.created_at
  Micropost Load (0.2ms)  SELECT "microposts".* FROM "microposts" ORDER BY "microposts"."created_at" DESC LIMIT ?  [["LIMIT", 1]]
=> Sun, 08 Oct 2023 21:37:34.533382000 UTC +00:00
irb(main):002:0> Micropost.last.created_at
  Micropost Load (0.3ms)  SELECT "microposts".* FROM "microposts" ORDER BY "microposts"."created_at" ASC LIMIT ?  [["LIMIT", 1]]
=> Sun, 08 Oct 2023 07:00:16.111795000 UTC +00:00

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

irb(main):003:0> Micropost.first
  Micropost Load (0.2ms)  SELECT "microposts".* FROM "microposts" ORDER BY "microposts"."created_at" DESC LIMIT ?  [["LIMIT", 1]]
Micropost.last
  Micropost Load (0.1ms)  SELECT "microposts".* FROM "microposts" ORDER BY "microposts"."created_at" ASC LIMIT ?  [["LIMIT", 1]]

注目して欲しいのは降順か、照準かということになります
Micropost.firstは"created_at" DESC
つまり降順から最初の投稿を拾っているのに対し
Micropost.lastはcreated_at" ASC
つまり昇順から拾っています

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

#userを代入

 user = User.first

user.microposts.first

 id: 1,
 content: "Lorem ipsum",
 user_id: 1,
 created_at: Sun, 08 Oct 2023 07:00:16.111795000 UTC +00:00,
 updated_at: Sun, 08 Oct 2023 07:00:16.111795000 UTC +00:00>


#ユーザーを削除
irb(main):003:0> user.destroy

 id: 1,
 name: "Example User",
 email: "example@railstutorial.org",
 created_at: Sun, 01 Oct 2023 08:28:59.861078000 UTC +00:00,
 updated_at: Tue, 03 Oct 2023 20:58:27.716591000 UTC +00:00,
 password_digest: "$2a$12$0bjsfJOdgTsq9bBRNTJFbu7.Z7LEPIoz4Q8KJIjcxX9UOOu5LcK2a",
 remember_digest: "$2a$12$T159OCf/5y10RMmQb8zCH.KLUna7G3CJFpbnJn1zr73jcNk8OKA.C",
 admin: true,
 activation_digest: "$2a$12$pkJnv9FWgk753jd0oPM4TeV7y4P2q7fZNgfTXZH.D.ATGhwZrAnz2",
 activated: true,
 activated_at: Sun, 01 Oct 2023 08:28:59.606888000 UTC +00:00,
 reset_digest: "$2a$12$O6oFLkLe8Cc81C0VCQPi2.sDODGvr801KmgmZ0G/AgSffQ1xz6FqO",
 reset_sent_at: Tue, 03 Oct 2023 20:58:27.716286000 UTC +00:00>

#マイクロポストを検索
 Micropost.find
/usr/local/rvm/gems/default/gems/activerecord-7.0.4.3/lib/active_record/relation/finder_methods.rb:455:in `find_with_ids': Couldn't find Micropost without an ID (ActiveRecord::RecordNotFound)

演習5

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(3.weeks.ago)
=> "21 days"
irb(main):005:0> helper.time_ago_in_words(6.month.ago)
=> "6 months"

helper.time_ago_in_words(1.year.ago)と実行すると、どういった結果が返ってくるでしょうか?

helper.time_ago_in_words(1.year.ago)
=> "about 1 year"

micropostsオブジェクトのクラスは何でしょうか? (ヒント: リスト 13.24内のコードを参考に、まずはpaginate(page: nil)でオブジェクトを取得し、その後classメソッドを呼び出してみましょう。)

user.microposts.paginate(page: nil)
  Micropost Load (2.4ms)  SELECT "microposts".* FROM "microposts" WHERE "microposts"."user_id" = ? ORDER BY "microposts"."created_at" DESC LIMIT ? OFFSET ?  [["user_id", 1], ["LIMIT", 30], ["OFFSET", 0]]
=> []
irb(main):012:0> user.microposts.paginate(page: nil).class
=> Micropost::ActiveRecord_AssociationRelation

演習6

(1..10).to_a.take(6)というコードの実行結果を推測できますか? 推測した値が合っているかどうか、実際にコンソールを使って確認してみましょう。[

1から10までの値のうち、6までを順番に取り出しました

(1..10).to_a.take(6)
=> [1, 2, 3, 4, 5, 6]

上の演習にあったto_aメソッドの部分は本当に必要でしょうか? 確かめてみてください。

必要ありません。

 (1..10).take(6)
=> [1, 2, 3, 4, 5, 6]

Fakerはlorem ipsum以外にも、非常に多種多様の事例に対応しています。Fakerのドキュメント(英語)を眺めながら画面に出力する方法を学び、実際に架空の大学名やHipster IpsumやChuck Norris facts(参考: チャック・ノリスの真実)を画面に出力してみましょう。

Faker::University.name
=> "Southern Kutch College"
Faker::Hipster.word
=> "taxidermy"
Faker::ChuckNorris.fact
=> "When Chuck Norris gives a method an argument, the method loses."

余談ですが、ちゃんと日本のキャラクターも生成できるようです笑

irb(main):014:0> Faker::JapaneseMedia::DragonBall.character
=> "Shenron"
irb(main):015:0> Faker::JapaneseMedia::DragonBall.character
=> "Android 16"
irb(main):016:0> Faker::JapaneseMedia::DragonBall.character
=> "Super Saiyan Trunks"
irb(main):017:0> Faker::JapaneseMedia::DragonBall.character
=> "Guru"
irb(main):018:0> Faker::JapaneseMedia::DragonBall.character
=> "Chi-Chi"

fakerのgithubのREAD.meの下の方にあるので、遊んでみてください

スクリーンショット 2023-10-10 155222.png

演習7

リスト 13.29にある2つの'h1'のテストが正しいか確かめるため、該当するアプリケーション側のコードをコメントアウトしてみましょう。テストが green から red に変わることを確認してみてください。

該当するのが'users/show'の部分のため、show.html.erbをのぞいてみましょう
このコードからh1タグをコメントアウトしてみます

app/views/users/show.html.erb

<% provide(:title, @user.name) %>
<div class="row">
  <aside class="col-md-4">
    <section class="user_info">
      <%# <h1> %>
        <%= gravatar_for @user %>
        <%= @user.name %>
      <%# </h1> %>
    </section>
  </aside>
  <div class="col-md-8">
    <% if @user.microposts.any? %>
      <h3>Microposts (<%= @user.microposts.count %>)</h3>
      <ol class="microposts">
        <%= render @microposts %>
      </ol>
      <%= will_paginate @microposts %>
    <% end %>
  </div>
</div>

h1が無かったよというエラーが発生します

UsersProfileTest#test_profile_display (2.57s)
        Expected at least 1 element matching "h1", found 0.
        Expected 0 to be >= 1.
        test/integration/users_profile_test.rb:14:in `block in <class:UsersProfileTest>'

  72/72: [=======================================================================================================================] 100% Time: 00:00:02, Time: 00:00:02

Finished in 2.82599s
72 tests, 230 assertions, 1 failures, 0 errors, 0 skips

リスト 13.29にあるテストを変更して、will_paginateが1回だけ表示されていることをテストしてみましょう。(ヒント: 表 5.2を参考にしてください。)

require "test_helper"

class UsersProfileTest < ActionDispatch::IntegrationTest
  include ApplicationHelper

  def setup
    @user = users(:michael)
  end

  test "profile display" do
    get user_path(@user)
    assert_template 'users/show'
    assert_select 'title', full_title(@user.name)
    assert_select 'h1', text: @user.name
    assert_select 'h1>img.gravatar'
    assert_match @user.microposts.count.to_s, response.body
    assert_select 'div.pagination',count: 1  #ここを追加
    @user.microposts.paginate(page: 1).each do |micropost|
      assert_match micropost.content, response.body
    end
  end
end

演習8

なぜUsersコントローラ内にあるlogged_in_userフィルターを残したままにするとマズイのでしょうか? 考えてみてください。

各コントローラが継承するApplicationコントローラに移したため、UsersでもMicropostsでも共通して使用できるようになったため、わざわざUsersコントローラー内に置くのはコードが重複して無駄が多くなるためです

演習9

Homeページをリファクタリングして、if-else文の分岐のそれぞれに対してパーシャルを作ってみましょう。

まずはhome.html.erbを条件分岐だけを残し、2つの新しいファイルを作成し
そのファイル内に条件分岐するコードを入れ、パーシャルしていきます

app/views/static_pages_home.html.erb

<% if logged_in? %>
  <%= render 'static_pages/home_logged_in' %>
<% else %>
  <%= render 'static_pages/home_not_logged_in' %>
<% end %>

続いて2つのファイルを作成しましょう

touch app/views/static_pages/_home_lodgged_in.html.erb
touch app/views/static_pages/_home_not_logged_in.html.erb

その中にコードを入れていきます

app/views/static_pages/_home_lodgged_in.html.erb

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

app/views/static_pages/_home_not_logged_in.html.erb

 <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.svg", alt: "Rails logo", width: "200px"),
              "https://rubyonrails.org/" %>

マイクロポストを投稿した直後に、ブラウザの更新ボタンを押すとエラーが表示されます。なぜエラーが表示されるのでしょうか?その原因を考えてみましょう。

私は上記方法を試してみましたが、特にエラーが出ませんでした。
恐らくこのページのこのコードが影響しているはずです

app/controllers/microposts_controller.rb

  def create
    @micropost = current_user.microposts.build(micropost_params)
    if @micropost.save
      flash[:success] = "Micropost created!"
      redirect_to root_url
    else
      render 'static_pages/home', status: :unprocessable_entity
    end
  end

ここで投稿に失敗した場合、renderで'static_pages/home'が反映されますが、これはただこのページを反映しているだけで、この状態で更新してもルーティング上にGETリクエストが存在しないため、ルートエラーになる?のかなと思います。
実はここの解答ですが、読み進めていくとこれに対する説明が書いてあります

スクリーンショット 2023-10-12 154322.png

そこから考えるにやはり/micropostsにはgetが必要であるなと言うことが分かりますね

もし上記の現象に対応するとしたら、どんな対応方法があるでしょうか?その対応方法を考えてみましょう。(ヒント: さまざまな対応方法がありますが、対応方法によっては今後の実装に支障が出ることがあります。ここでは対応方法のアイデア出しに留めておきましょう。)

redirect_toなどを使い、失敗した場合は、root_urlに戻るのが一番良いのではないかと思います

演習10

新しく実装したマイクロポストの投稿フォームを使って、実際にマイクロポストを投稿してみましょう。Railsサーバーのログ内にあるINSERT文では、どういった内容をデータベースに送っているでしょうか? 確認してみてください。

"content", "user_id", "created_at", "updated_at"
この4つをデータベースに送っているようですね

INSERT INTO "microposts" ("content", "user_id", "created_at", "updated_at")
VALUES (?, ?, ?, ?)  [["content", "test"], ["user_id", 1], 
["created_at", "2023-10-12 06:53:29.340704"], ["updated_at", "2023-10-12 06:53:29.340704"]]

コンソールを開き、user変数にデータベース上の最初のユーザーを代入してみましょう。その後、Micropost.where("user_id = ?", user.id)とuser.microposts、そしてuser.feedをそれぞれ実行してみて、実行結果がすべて同じであることを確認してみてください。(ヒント: ==で比較すると結果が同じかどうか簡単に判別できます。)

user = User.first
User Load (0.1ms)  SELECT "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT ?  [["LIMIT", 1]]

Micropost.where("user_id = ?"
user.microposts
user.feed
# 表示結果が共に長いので、省略

Micropost.where("user_id = ?", user.id) == user.microposts
  Micropost Load (5.8ms)  SELECT "microposts".* FROM "microposts" WHERE (user_id = 1) ORDER BY "microposts"."created_at" DESC
=> true

 user.microposts == user.feed
  Micropost Load (4.8ms)  SELECT "microposts".* FROM "microposts" WHERE "microposts"."user_id" = ? ORDER BY "microposts"."created_at" DESC  [["user_id", 1]]
  Micropost Load (48.4ms)  SELECT "microposts".* FROM "microposts" WHERE (user_id = 1) ORDER BY "microposts"."created_at" DESC
=> true

演習11

マイクロポストを作成し、その後、作成したマイクロポストを削除してみましょう。次に、Railsサーバーのログを開いて、DELETE文の内容を確認してみてください。

DELETE FROM "microposts" WHERE "microposts"."id" = ?  [["id", 14105]]
  ↳ app/controllers/microposts_controller.rb:17:in `destroy'

リスト 13.56の2つのリダイレクトを、redirect_back_or_to(root_url, status: :see_other)と1行で置き換えてもうまく動くことを、ブラウザを使って確認してみましょう。これは、参照元URLがnilである場合は指定のURLにリダイレクトします。

 def destroy
    @micropost.destroy
    flash[:success] = "Micropost deleted"
    if request.referrer.nil?
      redirect_back_or_to(root_url, status: :see_other)
    end
  end

演習12

リスト 13.59で示した4つのテスト項目が正しく動いているかをテスト項目ごとに確認してみましょう。具体的には、対応するアプリケーション側のコードをコメントアウトし、テストが red になることを確認し、元に戻すと green になることを確認してみましょう。

テスト6つじゃない?と思いますが、こちらは動作確認のため、いったんパスします

サイドバーにあるマイクロポストの合計投稿数のテストを追加してみましょう。このとき、単数形のmicropostと複数形のmicropostsが正しく表示されているかどうかもテストしてください。(ヒント: リスト 13.61を参考にしてみてください。)

  test "should display the right micropost count" do
    get root_path
    assert_match "#{@user.microposts.count} microposts", response.body
  end

  test "should user proper pluralization for zero microposts" do
    log_in_as(users(:malory))
    get root_path
    assert_match "0 microposts", response.body
  end

  test "should user proper pluralization for one micropost" do
    log_in_as(users(:lana))
    get root_path
    assert_match "1 micropost", response.body
  end

演習13

画像付きのマイクロポストを投稿してみましょう。画像が大きすぎますか?(次の13.4.3で画像サイズの問題を修正します)。

めちゃ大きいです

スクリーンショット 2023-10-13 161621.png

リスト 13.67に示すテンプレートを参考に、13.4で実装した画像アップローダーをテストしてください。テストの準備として、まずはターミナルでリスト 13.66を入力し、サンプル画像をfixtureディレクトリに追加してください。継続を表すバックスラッシュ記号\は入力が必要ですが、シェルで自動的に追加される2行目冒頭の >記号は入力しないようご注意ください。リスト 13.67で追加したアサーションでは、Homeページにあるファイルアップロードと、投稿に成功した時に画像が表示されているかどうかをチェックしています。なお、テスト内にあるfixture_file_uploadというメソッドは、fixtureで定義されたファイルをアップロードする特別なメソッドです22 。(ヒント: image属性が有効かどうかを確かめるときは、11.3.3で紹介したassignsメソッドを使ってください。このメソッドを使うと、投稿に成功した後にcreateアクション内のマイクロポストにアクセスするようになります。)

test/integration/microposts_interface_test.rb

 class ImageUploadTest < MicropostsInterface

    test "should have a file input field for images" do
      get root_path
      assert_select 'input[type=file]'
    end
  
    test "should be able to attach an image" do
      cont = "This micropost really ties the room together."
      img  = fixture_file_upload('kitten.jpg', 'image/jpeg')
      post microposts_path, params: { micropost: { content: cont, image: img } }
      assert assigns(:micropost).image.attached?
    end
end

演習14

5MB以上の画像ファイルを送信しようとした場合、どうなりますか?

下記画像のようなアラートが出現します
スクリーンショット 2023-10-13 164845.png

無効な拡張子のファイルを送信しようとした場合、どうなりますか?

そもそも無効な拡張子が選択できないようになっていたので、送信できませんでした

演習15

サイズの大きい画像をアップロードし、リサイズされているかどうか確認してみましょう。画像が長方形の場合も正しくリサイズされていますか?

正しくリサイズされています

スクリーンショット 2023-10-16 041829.png

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?