Things to remember and concepts in the Ruby on Rails tutorial

Introduction

I studied Rails to change jobs to a web-based in-house development company! As part of that study, I'm doing the 6th edition of the Rails tutorial, and I'll mention that I thought this was __important & __ to remember.

--Those who have done a Rails tutorial but haven't really thought about it ――What can you learn from Rails tutorials? Those who think --Those who want to review and learn the basics of creating apps with Rails I think this article will be helpful!

Basic terms and concepts of Ruby and Rails

★ What is a gem? --A Ruby package published by RubyGems --A package management system that manages those packages

★bundle install --Command to install what is required for Rails development described in Gemfile

★rails db:migrate --Functions used when changing the structure (table, column) of the database used by rails ・ Rough flow of using rails db: migrate

  1. Create a migration file & describe the contents
  2. Make changes to the database by running migrations in sequence with the $ rails db: migrate command

Chapter 5 Creating a layout

5.2.1 Asset pipeline

__ The asset pipeline is divided into three main functions (below). __ (* Explanation ★ Brief summary)

[The biggest advantage of the asset pipeline] Assets optimized for efficiency in production applications are also automatically generated. (= It will automatically load the page faster in the production environment.) By doing so, it is possible to maintain the readability of the file in the development environment and provide the strongest environment for each of the two different environments of "increasing the execution speed of the application in the production environment". ★ In short, both "development environment" and "production environment" are optimized, and it is the most efficient / convenient.

  1. Asset directory
  1. Manifest file
 *= require_tree . #app/assets/I try to include all the CSS files in the stylesheets
 *= require_self  #Manifest file(application.css)I try to include myself

Sporockets is reading comments like the one above in the manifest file.

  1. Preprocessor engine

★ In short, the assets are put together to make it easier to use in the browser.

5.3.4 Link testing

    assert_select "a[href=?]", help_path, 
<a href="/help”>...</a>
    assert_select "a[href=?]", root_path, count: 2

Count means that there are two links to root_path and you want to test two.

There are various ways to specify assert_select. Below are some typical examples. image.png

Summary of Chapter 5

--Rails partials are used for efficiency and you can cut out markup in a separate file. --The Bootstrap framework allows you to quickly implement responsive and good designs --Sass and Asset Pipeline compress redundant parts of CSS (separated for development efficiency) and output production-optimized results --Rails routing allows you to freely define rules, and at that time you can also use named routes. --Integration testing can efficiently simulate page feeling transitions.

Chapter 6 Creating a User Model

6.1 User model

Active Record: The default Rails library that interacts with the database

When creating a model, use the command generate model. Example) Creating a User model with attributes such as name and email

$ rails generate model User name:string email:string

[Rails naming convention] --Controller name: Plural (Example: Users) --Model name: Singular (Example: User) └ Because the model represents one user --Table name: Plural └Because the table (DB) has information of multiple users

6.1.3 Create a user object

--user = User.new: Instantiation --user.save: Save model

>> user = User.new(name: "Michael Hartl", email: "[email protected]")
>> user.save

--User.create: How to create and save a model at the same time through Active Record

>> User.create(name: "Another Sky”, email: "[email protected]")

--Access to model (. ) Example)

>> user.name
=> "Michael Hartl"
>> user.email
=> "[email protected]"
>> user.updated_at
=> Mon, 23 May 2016 19:05:58 UTC +00:00

--How to search in Active Record in the order in which the data was formed

>> User.find(1)
=> #<User id: 1, name: "Michael Hartl", email: "[email protected]",
created_at: "2019-08-22 01:51:03", updated_at: "2019-08-22 01:51:03">

--How to search for users by specific attributes (data) in Active Record

>> User.find_by(email: "[email protected]")
=> #<User id: 1, name: "Michael Hartl", email: "[email protected]",
created_at: "2019-08-22 01:51:03", updated_at: "2019-08-22 01:51:03">

6.2 Validate users

Validation case often used in Active Record

  1. Presence
  2. Length
  3. Format
  4. Uniqueness

__ How to proceed with test-driven development testing __

  1. Create a valid model object
  2. Intentionally change one of its attributes to an invalid attribute
  3. Test if validation fails
  4. Just in case, write a test for the state at the time of creation first, and check whether the first model is valid. By testing 5. 4., when the validation test fails, you can check whether there was a problem with the validation implementation or the object itself.

rails test: models: Command to run only tests on models

$ rails test:models

6.3.1 Hashed password

The migration name can be specified freely. By specifying the end (to_users), Rails will automatically create a migration that adds columns to the users table.

Example) To generate a migration file called add_password_digest_to_users, execute the following command.

$ rails generate migration add_password_digest_to_users password_digest:string

Summary of Chapter 6

--Active Record gives you many methods for creating and manipulating data models --Active Record Validation allows you to add limits to your model --Common Validations are "Does it exist?" "Length" "Format" --Adding an index to the database will dramatically improve search efficiency, and you can use the index to ensure uniqueness at the database level.

Chapter 7 User Registration

7.3.3 Error message

"Shared": Partials used by multiple views are in a dedicated directory

7.3.4 Test on failure

assert_select: Test target is CSS ・ For class → id name of div # CSS

assert_select 'div#error_explanation'

For class → div.CSS class name

assert_select 'div.field_with_errors'

7.6.1 Summary of this chapter

--Significant debug information can be displayed by using the debug method. --By using the mixin function of Sass, you can put together CSS rules and use the CSS information specified by the mixin in other places like variables. --Rails makes it easy to manage data through standard RESTful URLs --form_with helper creates a form for Active Record objects --You can use the flash variable to display a temporary message --Integration testing can be used to verify the behavior of submission forms and detect the occurrence of bugs.

Chapter 8 Basic Login Mechanism

8.1 Session

--_ __ HTTP is a stateless protocol __ --A protocol without state management --It is treated as an independent transaction (processing) without using the information of the previous and next requests at all. --So there is no "means" to hold information such as user ID in the HTTP protocol.

--When managing user information etc. on the Web application, it is necessary to separately set a semi-persistent connection between the client and server in "Session".

8.1.5 Flash test

What is assert_template: Tests if the URL after assert_template renders the view.

  • In the following cases, test whether sessions / new is drawing the view
    assert_template 'sessions/new'

Column 8.1. 「||=What is "?"

Ruby is designed to look at nil and false and make every object true. In Ruby||When using several operators in a row in an expression, it is designed to evaluate the terms in order from the left and finish the process when it first becomes true. This evaluation method is called short-circuit evaluation.

The __ && __ operator has a similar design, except that the term is evaluated from the left and the process ends when it first becomes false.

8.2.4 Test layout changes

.& __safe navigation operator(Or"Bocchi operator)__ 


 With Ruby's Bocchi operator, you can write patterns like obj && obj.method in a condensed form like obj & .method.
 To give an example, the following logical operator code

```ruby

    if user && user.authenticate(params[:session][:password])

It can be simplified as follows.


    if user&.authenticate(params[:session][:password])

&& user.authenticate is&.It can be simplified as authenticate.


 Isn't it too simplistic for a Ruby beginner? I'm a little confused, but
 It seems that the Bocchi operator is often used, so it seems that you need to make an effort to try and remember it yourself.

#### 8.4.1 Summary of this chapter
 --You can use Rails' ``` session``` method to keep the state at the time of page transition. You can also use cookies to keep a temporary state. (* Since all browsers will prohibit cross-domain cookie sharing in the future, Rakuten ○ ID etc. acquired in Rakuten ○ domain can no longer be used in another domain (domain other than Rakuten ○).)
 --You can temporarily save the user ID etc. in the browser by using the ``` session``` method.
 --Test Driven Development (TDD) is useful for preventing regression bugs
 --Integration strike allows you to test if routing, DB updates, and layout changes are being performed successfully

## Chapter 9 Advanced Login Mechanism
#### 9.1.1 Memory token and encryption
 There are four well-known ways to steal cookies.
 1. Extract cookies directly from network packets that pass through a poorly managed network with a special software called packet sniffer.
 2. Extract the storage token from the DB
 3. Use cross-site scripting (XSS)
 4. Steal access by directly operating the PC or smartphone on which the user is logged in

 The countermeasure of 1. is to support the site with SSL of 7.5
 Correspondence of 2. In this tutorial, the storage token is stored in the DB as __hashing__.
 The correspondence of 3. is automatically dealt with in Rails
 4. It is impossible to take fundamental defense measures on the system side

 ■ Usage of attr_accessor
 When you want to define the attributes of an object that can be read and written
 
 -How to define a User object with attributes name and description
 For Rails

```ruby

class CreateUsers < ActiveRecord::Migration
  def change
    create_table :users do |t|
      t.string :name
      t.string :description

      t.timestamps null: false
    end
  end
end

For pure Ruby code that doesn't deal with DB


class User
  attr_accessor :name, :description
end

By the way, attr_reader is used when you want to define read-only attributes. attr_writerIs used when you want to define write-only attributes.

Column 9.2. 10 kinds of people

"There are 10 kinds of people in this world. Some people can understand binary and some can't understand binary" is a joke that has been passed down in the industry for a long time. It's like Roland (laughs) Maybe Roland got stuck from here? ??

■ Ternary operator The following if else code

  if boolean?
    var = foo
  else
    var = bar
  end

Can be shortened as follows

var = boolean? ? foo : bar

We often use the ternary operator as the return value of a method.

  • Judge the execution result of the function with true or false.

9.3.2 Test [Remember me]

assert_equalIs ,Arrange the values in the order of .

assert_equal <expected>, <actual>

9.4.1 Summary of this chapter

--In Rails, "state" can be retained at the time of page transition. If you want to keep the page state for a long time, use the `cookies``` method to make it a persistent session. --A persistent session can be realized by associating remember_token and remember_digest for each user. --You can use the `cookies``` method to save cookies etc. in your browser -(Generally) deleting sessions and cookies respectively can achieve user logout

Chapter 10 User Update / Display / Delete

10.1 Update user

target="_blank"Use to link to a new tab(Or window)This is a useful element when linking to another website because it will open in. ★ Personally, I'm happy with another tab when I jump to the link destination, so when I implement it, I definitely want to implement it! Personally, I think that sites for PCs (assuming PCs are the main clients) should definitely be introduced!

<a href="https://gravatar.com/emails" target="_blank">change</a>

Rails uses form_with (@user)` `` to construct a form, and when` `@ user.new_record?` `` Is` `true, it is POST. , `` `PATCH when ``` false``.

10.2.3 Friendly forwarding

In __ * Tutorial, user is used instead of @user, but if you use it, an error will occur in users_login_test, so use @user. __

sessions_controller.rb


  def create
    @user = User.find_by(email: params[:session][:email].downcase)              #Lowercase the email value received in the params hash, pass it to the email attribute, find the User with the same email value in the User model, and assign it to the user variable
    if @user && @user.authenticate(params[:session][:password])                 #The user variable exists in the database, and the password value received in the params hash is the same as the user's email value.(If the password and email address are the same value)true
      log_in @user                                                              # sessions_helper log_Execute in method and user of session method_Send id to id (stored as temporary cookies in your browser)
      params[:session][:remember_me] == '1' ? remember(@user) : forget(@user)   #Remember session at login_me attribute is 1(Check box is on)If so, destroy the session permanently, otherwise destroy the persistent session
      redirect_back_or @user                                                    #Redirect to the previous page of user or default
    else
      flash.now[:danger] = 'Invalid email/password combination'                 #Show a flash message and turn it off when a new request occurs
      render 'new'                                                              #New view output
    end
  end
  • Actual error statement
Error:
UsersLoginTest#test_login_with_remembering:
NoMethodError: undefined method `remember_token' for nil:NilClass
    test/integration/users_login_test.rb:60:in `block in <class:UsersLoginTest>'

10.5.1 Summary of this chapter

--The user sends a PATCH request to the update action from the edit form to update the information --By using Strong Prameters (params [: foobar]), you can safely change it from the web. --By using the before filter, you can call the method before a specific action 4 is executed (* It's very convenient !! It seems to have various uses !!) --In the Authorization test, we ran two tests: a simple test that sends a specific HTTP request directly, and a difficult test (integration test) that simulates the operation of the browser (the operation that the user actually does). (Personally, thinking about the tests needed to simulate an integration test had to be logical, and it was fun to think constructively.) --Friendly forwarding is absolutely necessary when creating an actual app, so you should remember and actively implement it (UX basically friendly forwarding is essential) --The `rails db: seed``` command flushes the sample data in db / seeds.rb``` into the DB --When you run ``` render @ users```, it will automatically reference the `_user.html.erb``` partial and display each user as a collection. --When you add a boolean admin attribute to your User model, a method that returns a logical object called admin? Is automatically added.

Chapter 11 Account Activation

User Activation flow

  1. The initial state of the user is set to "unactivated".
  2. When user registration is performed, an activation token and the corresponding activation digest are generated.
  3. Save the activation digest in the database, and put the activation token in the link of the activation email sent to the user together with the email address.
  4. When the user clicks on the link in the email, the application uses the email address as a key to find the user and authenticates the token by comparing it to the activation digest stored in the database.
  5. After authenticating the user, change the user's status from "not activated" to "activated".

11.3.3 Activation testing and refactoring

assignsMethods allow you to access instance variables in the corresponding action. For example, in the `create``` action of the Users controller, there is an instance variable @ user```, but if you write ```assigns (: user) `` in the test, it will be in the user instance variable. You will be able to access it.

I got an error in test. .. Refer to this teratail article and use the following code

  def create
    user = User.find_by(email: params[:session][:email].downcase)
    if user && user.authenticate(params[:session][:password])
      if user.activated?
        log_in user
        params[:session][:remember_me] == '1' ? remember(user) : forget(user)
        redirect_back_or user
      else
        message  = "Account not activated. "
        message += "Check your email for the activation link."
        flash[:warning] = message
        redirect_to root_url
      end
    else
      flash.now[:danger] = 'Invalid email/password combination'
      render 'new'
    end
  end

I succeeded by doing the following ~

  def create
    @user = User.find_by(email: params[:session][:email].downcase)
    if @user && @user.authenticate(params[:session][:password])
      if @user.activated?
        log_in @user
        params[:session][:remember_me] == '1' ? remember(@user) : forget(@user)
        redirect_back_or @user
      else
        message  = "Account not activated. "
        message += "Check your email for the activation link."
        flash[:warning] = message
        redirect_to root_url
      end
    else
      flash.now[:danger] = 'Invalid email/password combination'
      render 'new'
    end
  end

11.5.1 Summary of this chapter

--Account activation is not an Active Record object, but can be modeled with resources as it is for sessions --Rails can generate Action Mailer actions and views for sending emails --Action Mailer can use both text mail and HTML mail --The instance variables defined in Mailer Action can be referenced from the Mailer view like other actions and views. --Create a unique URL using the generated token to activate your account --SendGrid allows you to send emails from your production environment

Chapter 12 Password reset

12.3.3 Test password reset

-The assigns method is a method that tests the instance variables of the controller. Pass the instance variable as an argument as a symbol type. This will give you access to your instance variables and allow you to test them.

    @user = assigns(:user)

12.5.1 Summary of this chapter

--Rails can generate Action Mailer actions and views for sending emails --Use hashed tokens (digests) for more secure password reset

Chapter 13 User Micropost

13.4.1 Basic image upload

■Active Storage Images can be easily handled by using Active Storage, and the model associated with the images can be freely specified. Active Storage is highly versatile and can handle various binary files such as plaintext text, PDF files, and audio files.

The first thing you need to know about the Active Storage API is the has_one_attached method. This is used to associate the specified model with the uploaded file. has_one_attached can be used to associate the specified model with the uploaded file. In the case of has_one_attached, "1 image per Microsoft", You can use has_many_attached to attach "multiple images per Microsoft".

13.5.1 Summary of this chapter

--Rails supports multiple key indexes --User has multiple Microposts (has_many) and Micropost depends on one User (belongs_to) --The code user.microposts.build (...) returns the microposts associated with the user given as an argument. --Use the dependent:: destroy option to delete the associated object and itself at the same time. --fitten also supports creating objects using associations --Variables can be passed together when calling a partial --You can select (extract a subset) through Active Record by using the `` `where``` method. * You can get it with the same sentence as the raw SQL statement.

Chapter 14 Follow Users

14.2.2 Statistics and Follow Form

@user ||= current_user

The above code does nothing if @ user is not nil, and assigns current_user to @ user``` if it is nil.

14.4.3 Summary of this chapter

--has_many: through allows you to model complex data relationships --You can pass a number of options to the has_many method, such as class names and foreign keys. --By using has_many / has_many: through with the appropriate class name and foreign key, we were able to model active and passive relationships (following). --Routing can be used nested --where method allows you to create flexible and powerful database queries --Rails can call low-level SQL queries (if needed)

Extra edition

__ ■ Assert list __

Method Description
assert_template(expected, message = nil) Check if the template specified in the action is depicted
assert_not( test, [msg] ) __test__But__false__Check if.
assert_select "div.nav" selector(div)The content of the element that matches the argument equality(nav)Check at
  • Assert_select is a flexible and powerful feature with many options, but it's best to limit it to testing HTML elements (such as links) that change frequently in your layout.

■ __ "!!" (read as "bang bang") __ An operator that can convert an object to a Boolean value. nil will be false.

>> !!nil
=> false

Every other Ruby object is true, even zero.

>> !!0
=> true

■! About the exclamation mark ◆ By using the! Mark, you can directly change the data (~ ~ attribute). When not using ★!

  before_save { self.email = email.downcase }

When using ★!

  before_save { email.downcase! }

◆ You can raise exception by adding! To a method! !! Example with create, save. Without! (Create save) -When the process is executed and record creation / saving fails, `` `nilis returned. When adding! (Create! save!) Exceptions (egActiveRecord :: RecordNotFound ERROR```) can be raised.


■ HTML __type = “email” __ If you set __type = “email” __ in html, tap the input form from your mobile phone and you will see a special keyboard optimized for your email address.

`private` keyword --Used to define methods that are only used within that file (class) --Methods defined in private cannot be used in other files (classes). --Unexpected errors can be avoided by making methods private that are not used in other files.

  private

    def user_params
      params.require(:user).permit(:name, :email, :password, :password_confirmation)
    end

PATCH Method for HTTP --Put method replaces rather than updates --Replace the value with Puts even if the replacement destination is "empty" (substitute the value you are trying to replace as it is) --Patch method updates / modifies / modifies existing resources

■ << Operator (Shovel Operator) <<You can add it to the end of the array with.

user.following << other_user

at the end

It took quite a while. .. It took about a month as a result, although it was accompanied by Cloud9 errors. .. I think it can't be helped because it was quite volumey, but there are people who finish it earlier, so I will finish making Portfolio sooner! !!

Thank you for reading! !!

Recommended Posts