[RUBY] (Giri) A local government employee in his twenties works on a Rails tutorial [Chapter 7]

Premise

・ Rails tutorial is the 4th edition ・ This study is the 3rd lap (2nd lap after Chapter 9) ・ The author is a beginner who has done all of Progate.

Basic policy

・ If you read it, you will not understand it. ・ Search and summarize terms that you do not understand (at the bottom of the article, glossary). ・ Dive into what you do not understand. ・ Work on all exercises. ・ Do not copy chords as much as possible.

Chapter 7 is the development of login and authentication system, the second stage, and the user registration function will be added.

Today's BGM is here in the daytime when it rains heavily (at the time of writing). Hitsujibungaku "Blue.ep" Hitsujibungaku again. Recent Favorites. The first song "Rain" is good.

[7.1.1 Debugging and Rails environment exercises]

  1. Access / about from your browser and check that the debug information is displayed. Which controller and action was used when displaying this page? Let's check the contents of params. → controller: static_pages   action: about

2. Open the Rails console, get the first user information from the database, and store it in the variable user. Then what do you see when you run puts user.attributes.to_yaml? Let's compare the result displayed here with the result of running y user.attributes using the y method. → Below. This way of writing is YAML. The result is the same.

>> user = User.first
  User Load (0.6ms)  SELECT  "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT ?  [["LIMIT", 1]]
=> #<User id: 1, name: "nakamura", email: "[email protected]", created_at: "2020-09-10 02:37:56", updated_at: "2020-09-10 03:07:11", password_digest: "$2a$10$A5n.HFBigQfwnWVJZw2N0e4M9sxPaR8ndLZwqtZWYS7...">

>> puts user.attributes.to_yaml
---
id: 1
name: nakamura
email: [email protected]
created_at: !ruby/object:ActiveSupport::TimeWithZone
  utc: &1 2020-09-10 02:37:56.040628000 Z
  zone: &2 !ruby/object:ActiveSupport::TimeZone
    name: Etc/UTC
  time: *1
updated_at: !ruby/object:ActiveSupport::TimeWithZone
  utc: &3 2020-09-10 03:07:11.190666000 Z
  zone: *2
  time: *3
password_digest: "$2a$10$A5n.HFBigQfwnWVJZw2N0e4M9sxPaR8ndLZwqtZWYS7gJGH/Ulohe"
=> nil

>> y user.attributes
---
id: 1
name: nakamura
email: [email protected]
created_at: !ruby/object:ActiveSupport::TimeWithZone
  utc: &1 2020-09-10 02:37:56.040628000 Z
  zone: &2 !ruby/object:ActiveSupport::TimeZone
    name: Etc/UTC
  time: *1
updated_at: !ruby/object:ActiveSupport::TimeWithZone
  utc: &3 2020-09-10 03:07:11.190666000 Z
  zone: *2
  time: *3
password_digest: "$2a$10$A5n.HFBigQfwnWVJZw2N0e4M9sxPaR8ndLZwqtZWYS7gJGH/Ulohe"
=> nil

[7.1.2 Users resource exercise]

  1. Using embedded Ruby, let's display the values of the magic columns (created_at and updated_at) on the show page (Listing 7.4).
  2. Let's display the result of Time.now on the show page using embedded Ruby. How does the result change when I refresh the page? Check it out. → Don all together! (Since it was annoying to be displayed sticking together, a line break is made with the p tag.) When the page is refreshed, the current time is updated and displayed.

ruby:show.html.erb


<p>
  <%= @user.name %>, <%= @user.email %>
</p>
<p>
  <%= @user.created_at %>, <%= @user.updated_at %>
</p>
<p>
  <%= Time.now %>
</p>

[7.1.3 debugger method memos and exercises]

If you don't understand the behavior, plug the debegger near the code that is likely to cause trouble!

  1. Insert the debugger into the show action (Listing 7.6) and try accessing / users / 1 from your browser. Then move to the console and use the puts method to display the contents of the params hash in YAML format. Tip: Please refer to the exercise in 7.1.1.1. How did you display the debug information displayed by the debug method in YAML format in that exercise? → Below
(byebug) puts @user.attributes.to_yaml
---
id: 1
name: nakamura
email: [email protected]
created_at: !ruby/object:ActiveSupport::TimeWithZone
  utc: &1 2020-09-10 02:37:56.040628000 Z
  zone: &2 !ruby/object:ActiveSupport::TimeZone
    name: Etc/UTC
  time: *1
updated_at: !ruby/object:ActiveSupport::TimeWithZone
  utc: &3 2020-09-10 03:07:11.190666000 Z
  zone: *2
  time: *3
password_digest: "$2a$10$A5n.HFBigQfwnWVJZw2N0e4M9sxPaR8ndLZwqtZWYS7gJGH/Ulohe"
nil

2. Insert the debugger into the new action and access / users / new. What does @user look like? Check it out. → Below

(byebug) @user
Started GET "/users/new" for 49.104.6.138 at 2020-09-10 06:51:27 +0000
#<User id: 1, name: "nakamura", email: "[email protected]", created_at: "2020-09-10 02:37:56", updated_at: "2020-09-10 03:07:11", password_digest: "$2a$10$A5n.HFBigQfwnWVJZw2N0e4M9sxPaR8ndLZwqtZWYS7...">

[7.1.4 Gravatar image and sidebar exercise]

There is an error here. Gravatar image is not displayed. Just in case, even if I overwrite the handwritten code with copy and paste, it is not displayed. That means ... Display: none; in SCSS But did you? After all, I searched while thinking. The time when the image was erased in the exercise of Chapter 5 remained. It's the work of a kitten! !! But forgive me because it's cute! !! I solved it by deleting the code of the img tag.

  1. (Optional) Create an account on Gravatar and try linking your email address with an appropriate image. MD5 hash your email address and see if the associated image is displayed properly. → It was displayed when I registered the image and created a new user on the console. gravatar.png

2. Let's change the gravatar_for helper defined in 7.1.4 as shown in Listing 7.12 so that size can be received as an optional argument. If you can change it well, you will be able to call gravatar_for user, size: 50. Important: This improved helper will actually be used in 10.3.1. Don't forget to implement it. → Just write as shown in Listing 7.12.

3. Optional arguments are still commonly used in the Ruby community, but can also be implemented with the new feature "Keyword Arguments" introduced in Ruby 2.0. Let's see that replacing the modified Listing 7.12 with Listing 7.13 works fine. What's the difference between the two implementations? Think about it. → Hmm, I've researched various things, but I don't understand the difference in behavior. I found that the advantage was that the notation could be simplified. I also found out the meaning of each term.

Keyword argument: Argument with a key set in the argument. Clarify what you put in the argument. Optional arguments: You can flexibly pass various values. Highly expandable. However, if the value to be passed increases, it will be difficult to maintain it later. Readability is also reduced.

So, is the keyword argument introduced in later versions for the purpose of writing code concisely? If you write the option argument, you're writing extra code in the size definition. Is it okay with such an answer?

[7.2.1 Exercise using form_for]

  1. As a test, let's replace: name in Listing 7.15 with: nome. What error message do you get? → undefined method `nome' for #User:0x00007f6b8d40b370
  2. As a test, try replacing all the variables f in the block with foobar and check that the result does not change. Sure, the result doesn't change, but foobar as the variable name doesn't seem to be a very good change. Think about why. → It's awkward to write simply, and f is f in form. Using unrelated words makes it harder to read. (I haven't posted any evidence, but I purposely rewrote everything to foobar!)

[7.2.2 Form HTML practice]

  1. Learn Enough HTML to Be Dangerous transcribes all HTML manually. Why didn't you use the form tag? Think about the reason. → I don't know from reading it, but it's because I don't use input / send. (Do not use it)

[7.3.2 Strong Parameters memos and exercises]

The mass assignment vulnerability that appeared in 7.3.1 is This article may be easy to understand.

  1. Access / signup? admin = 1 and check from the debug information that the admin attribute is included in params. → Is this it? --- !ruby/object:ActionController::Parameters parameters: !ruby/hash:ActiveSupport::HashWithIndifferentAccess admin: '1' controller: users action: new permitted: false

[7.3.3 Error message memo and exercise]

empty? Method: true if the object is empty, false otherwise any? Method: true if there is at least one element, false if there is none pluralize method: The meaning of a word is "plural (form)". As you can see, it pluralizes the English words of the arguments given later based on the integers of the arguments given to the visitor.

  1. Make sure that if you change the minimum number of characters to 5, the error message will be updated automatically. → Below. Password is too short (minimum is 5 characters) is displayed.

/models/user.rb


validates :password, presence: true, length: { minimum: 5 }

2. Compare the URL of the unsubmitted user registration form (Fig. 7.12) with the URL of the submitted user registration form (Fig. 7.18). Why are the URLs different? Think about it. → Before sending: ~ / signup * ~ is the AWS address After sending: ~ / users Since I am making a POST request for user registration, can I understand that it jumps to / users according to the users resource? (See Table 7.1 in the tutorial)

[7.3.4 Test memos and exercises at the time of failure]

The count method can be used with any Active Record class. From here on, the content of the test becomes complicated. Let's follow the meaning of each code. The exercises here are heavy, but let's think about it. (Please forgive me if I make a mistake)

  1. Write a test for the error message implemented in Listing 7.20. It's up to you how detailed you want to test. We have prepared a template in Listing 7.25 for your reference. → According to the template, it tests whether the CSSid and class of the error message are displayed, so if you rewrite the relevant part as follows, the test is GREEN.

users_signup_test.rb


assert_select 'div#error_explanation'
assert_select 'div.field_with_errors'

2. The URL of the user registration form is / signup, but if you send invalid user registration data, the URL will change to / users. This is a result of the difference between the named route (/ signup) added in Listing 5.43 and the default settings for RESTful routing (Listing 7.3). Use the contents of Listing 7.26 and Listing 7.27 to try to resolve this issue. Hopefully both URLs should be / signup. Oh, but the test is still green ... why? (Think about it) → According to the routing settings in Listing 7.26, there are two destinations after registration failure (URL is / users and / signup). As a result, both are in a state where they can be detected by the test, so they do not become RED.

3. Change the post part of Listing 7.25 to match the new URL (/ signup) created in the previous exercise. Also make sure that the test remains green. → Change users_path to signup_path. I just changed what is detected in the test, so it remains GREEN.

users_signup_test.rb


  test "invalid signup information" do
    get signup_path
    assert_no_difference 'User.count' do
      post signup_path, params: { user: { name: "",
  #(Omitted below)

4. Try returning the form in Listing 7.27 to its previous state (Listing 7.20) and make sure the test is still green. This is a problem! Because the URL where the post is currently being sent is incorrect. Let's add a test using assert_select to Listing 7.25 so that we can detect this bug (adding a test and getting red is successful). Then go back to the modified form (Listing 7.27) and see that the test turns green. Tip: Instead of submitting and testing from a form, focus on the presence of the'form [action = "/ signup"]' part. → Remove ", url: signup_path" from form_for (@user, url: signup_path). If registration actually fails in this state, the URL will be / users. Since this is no good, I added the following sentence to the test so that it can be detected. The result is RED. So when I return the form destination to the state shown in Listing 7.27 to make it / singup again, the test is GREEN. It took me a while to understand. If you can't understand Exercise 2, you can't understand the rest. Don't give up, research until you understand it, think about it, and solve it.

users_signup_test.rb


assert_select 'form[action="/signup"]'

[7.4.1 Completion of registration form Memo and exercise]

redirect_to @user → redurect_to user_url(@user) Railsf interprets and executes it without permission. What is the difference between redirect_to and reder? Do you mind? I'm curious. I was curious, so I looked it up. Since redirec_to specifies the URL, it seems that it is performing a series of operations through the router. Used when there is data update etc. When render is displaying the view directly. This is a simple process that does not involve data changes.

  1. Send valid information and use the Rails console to confirm that the user was actually created. → Register as a user from the actual registration screen and find appropriately on the console.

  2. Update Listing 7.28 and see that redirect_to user_url (@user) and redirect_to @user give the same result. → The same result will be obtained.

[7.4.2 flash exercise]

  1. Move to the console and call the symbol with the expression expansion (4.2.2) in the character string. For example, if you execute a code such as "# {: success}", what value will be returned? Check it. → Below. A string will be returned.
>> "#{:success}"
=> "success"

2. Consider what the flash in Listing 7.30 will look like, referring to the results you tried in the previous exercise. → I don't know what you're looking for, but what is this?

>> flash = { success: "It worked!", danger: "It failed." }
=> {:success=>"It worked!", :danger=>"It failed."}
>> "#{flash[:success]}"
=> "It worked!"
>> "#{flash[:danger]}"
=> "It failed."

[7.4.3 Actual user registration exercise]

  1. Use the Rails console to check again if a new user was really created. The result should look like Listing 7.32. → Just try it.

2. Try user registration with your own email address. If you have already registered with Gravatar, please check if the appropriate image is displayed. → Just try this too.

[7.4.4 Successful test exercise]

  1. Write a test for flash implemented in 7.4.2. It's up to you how detailed you want to test. I've provided a minimal template in Listing 7.34 for your reference (replace FILL_IN with the appropriate code and you're done). By the way, tests on text are fragile. It's the same for flash keys with less text. In my case, I often just test if the flash is empty. → OK if you put the empty? Method in FILL_IN.

  2. As I pointed out in the text, the HTML for flash (Listing 7.31) is difficult to read. Let's change to the code in Listing 7.35, which is easier to read. After making the changes, run the test suite to make sure it works. Note that this code uses Rails' content_tag helper. → Execute as instructed.

3. Let's confirm that the test fails when commenting out the redirect line in Listing 7.28. → It will fail.

4. Let's say you replaced @ user.save with false in Listing 7.28 (assuming you've embedded a bug). How would the assert_difference test detect this bug then? Take a look at the test code. → The following error occurs. Does that mean that the number of users hasn't increased?

 "User.count" didn't change by 1.
        Expected: 1
          Actual: 0

[7.5.3 Successful test exercise]

  1. Access the production environment (Heroku) from your browser and check if the SSL key mark is applied and if the URL is https. → It was locked.

2. Let's create a user in the production environment. Is the Gravatar image displayed correctly? → It was displayed.

Chapter 7 Summary

・ Sass is convenient after all. ・ Be careful about the difference between RESTfull routes and individually set routes. ・ How common is Gravatar? Is it popular from wordpress and so on? ・ Form_for seems to be replaced with form_with, so for reference. -Render and redirect_to are used properly. -Display a flash message. ・ Measures against mass assignment vulnerabilities with Strong Parameters. -Improved security with SSL.

The exercises in this chapter were crunchy. You need to think about each code and behavior as to why this happens. Let's work on it without giving up thinking. Next, let's prepare Chapter 8, the login mechanism.

Go to Chapter 8! Click here for Chapter 6 Click here for premise and author status for learning

A glossary that somehow captures the image

・ Assert_difference (assert_no_difference) Test whether the numerical value (result) given by the argument (assuming the usage in this chapter) is different before and after executing the block processing. The former is different, no_difference confirms that there is no difference.

・ SSL (Secure Sockets Layer) A protocol for communication that requires security. Currently, it has been replaced by TLS (Transport Layer Security), but it is called SSL as a remnant of the past.

Recommended Posts

(Giri) A local government employee in his twenties works on a Rails tutorial [Chapter 11]
(Giri) A local government employee in his twenties works on a Rails tutorial [Chapter 1]
(Giri) A local government employee in his twenties works on a Rails tutorial [Chapter 14]
(Giri) A local government employee in his twenties works on a Rails tutorial [Chapter 12]
(Giri) A local government employee in his twenties works on a Rails tutorial [Chapter 5]
(Giri) A local government employee in his twenties works on a Rails tutorial [Chapter 3]
(Giri) A local government employee in his twenties works on a Rails tutorial [Chapter 4]
(Giri) A local government employee in his twenties works on a Rails tutorial [Chapter 8]
(Giri) A local government employee in his twenties works on a Rails tutorial [Chapter 6]
(Giri) A local government employee in his twenties works on a Rails tutorial [Chapter 13]
(Giri) A local government employee in his twenties works on a Rails tutorial [Chapter 9]
(Giri) A local government employee in his twenties works on a Rails tutorial [Chapter 7]
(Giri) A local government employee in his twenties works on a Rails tutorial [Chapter 2]
(Giri) A local government employee in his twenties works on a Rails tutorial [Introduction]
[Ruby on Rails Tutorial] Error in the test in Chapter 3
[Rails Struggle/Rails Tutorial] What you learned in Rails Tutorial Chapter 6
(Ruby on Rails6) Creating data in a table
[Rails tutorial] A memorandum of "Chapter 11 Account Activation"
rails tutorial Chapter 7
rails tutorial Chapter 5
rails tutorial Chapter 10
rails tutorial Chapter 8
[Rails Tutorial Chapter 2] What to do when you make a mistake in the column name
Rails Tutorial Chapter 5 Notes
Rails Tutorial Chapter 10 Notes
Rails Tutorial Chapter 3 Notes
Rails Tutorial Chapter 3 Learning
Rails Tutorial Memorandum (Chapter 3, 3.1)
Rails Tutorial Chapter 4 Notes
Rails Tutorial Chapter 4 Learning
Rails Tutorial Chapter 1 Learning
Rails Tutorial Chapter 2 Learning
Rails Tutorial Chapter 8 Notes
Rails Tutorial Memorandum (Chapter 3, 3.3.2)
Difficulties in building a Ruby on Rails environment (Windows 10) (SQLite3)
How to display a graph in Ruby on Rails (LazyHighChart)
Apply CSS to a specific View in Ruby on Rails