Ruby on Rails6 Practical Guide [Extensions] cp3 ~ cp6 [Memo]

Introduction

The author of this article is a beginner just starting to learn programming. I would appreciate it if you could point out any mistakes.

Overview

This article is a personal memo of what I learned by reading the Ruby on Rails 6 Practical Guide. It seems to be difficult to read because it is excerpted and picked up. Excuse me. This book also has a sequel Extension, and both books have been studied at the stage of writing the article. I will write an article for review as well. I will skip cp1 and cp2 of the function extension because they explain the environment construction and the code of the main part.

Previous article Ruby on Rails6 Practical Guide cp4 ~ cp6 [Memo] Ruby on Rails6 Practical Guide cp7 ~ cp9 [Memo] Ruby on Rails6 Practical Guide cp10 ~ cp12 [Memo] Ruby on Rails6 Practical Guide cp13 ~ cp15 [Memo] Ruby on Rails6 Practical Guide cp16 ~ cp18 [Memo]

Function expansion Chapter 3 search form

name of index

The add_index method generates a name by default as follows:

However, there is a limit to the name of the index, so if you combine a large number of columns as a composite index, you may exceed the limit. In such cases, you need to specify the index name with the name option.

add_index :customers, [ :birth_year, :family_name_kana, :given_name_kana ],
  name: "index_customers_on_birth_year_and_furigana"

Composite index

If a composite index is set for columns X, Y, and Z, this composite index will be used for searches for column X alone, searches that combine columns X and Y, and searches that combine three columns. However, this composite index is not used for a search for column Y alone, a search for column Z alone, or a search for a combination of columns Y and Z. So, to optimize the search for all combinations, you need to set the index as below.


Difference between &. (Bocchi operator) and try method

Both methods return nil when the receiver is nil, but the behavior is slightly different when the receiver is other than nil. If you try to call a method that is not defined in the receiver with &., NoMethodError will occur, but if it is try, nil will be returned.

user&.name
user.try(:name)

In the above example, if there is no name in the instance method of user, NoMethodError will occur only when &. Is used.


Accumulate Relation objects

attr_accessor :name, :gender, :birthday

def search
  rel = User

  rel = rel.where(name: name) if name.present?
  rel = rel.where(gender: gender) if gender.present?
  rel = rel.where(birthday: birthday) if birthday.present?
  rel = rel.order(:name)
end

The code above is a form object. Defines a search object that returns search results. Since where and order return a Relation object, you can store various search conditions in the Relation object as in the code above.

Join tables with joins

rel = rel.joins(:articles)
rel = rel.where("articles.title" => title) if title.present?

The joins method does a table join </ strong>. Table joins allow you to filter records based on column values in other tables. The argument of the joins method is the name of the association. This method also returns a Relation object. When you join a table, you can search for other tables like the code in the second line.

Remove duplication

rel = rel.distinct

You can remove duplicates from the search results by calling the distinct method.

Function expansion Chapter 4 Automatic login from the next time

cookies

cookies.signed[:user_id] = user.id

Calling the signed method makes the cookie value unreadable and immutable.

cookies.permanent.signed[:user_id] = user.id

The permanent method sets the cookie expiration after 20 years.

cookies.delete(:user_id)

You can erase the ID recorded in the cookie with the above code.


Cookie test

expect(response.cookies).to have_key("customer_id")
expect(response.cookies["customer_id"]).to match(/[0-9a-f]{40}\z/)

The first line looks to see if the cookie has a key called "customer_id". The second line looks to see if the cookie value is disabled. Non-viewable cookies are characterized by having a 40-digit hexadecimal number at the end, so we are investigating this using regular expressions.

Function expansion Chapter 5 Access restrictions by IP address

Verify that the value is numeric

validates :octet1, numericality: { only_integer: true },
  inclusion: { in: 0..255 }

numericality verifies if the value is only a number. If you specify true for only_integer, only integers will be matched. With inclusion alone, a string like "XYZ" will be changed to the integer 0, so no error will occur. numericality will result in an error because validation is performed on the value before conversion.

The Rails Guide (https://railsguides.jp/active_record_validations.html#numericality) has more details.

Function expansion Chapter 6 Many-to-many association

Many-to-many associations can be divided into a combination of two one-to-many associations using a linked table.


Add a comma to separate numbers

number_with_delimiter(100000)

100,000 will be returned.


Count the number of many-to-many associations

When a customer and a program have a many-to-many relationship

program.cusotmers.count

You can count the number of participants in the program as follows. However, the performance will be worse because complicated queries using JOIN will be issued.

It is the same even if you count the link table applications (entry), so you can also write as below.

program.entries.count

Counting the number of linked tables will prevent complex queries from being issued and improve performance.

Solve the N + 1 problem

With the above code, the number of applicants is counted for each program, so there is an "N + 1 problem". The code below will allow you to get the number of applicants for each program with a single query.

Program.joins(:entries)
  .select("programs.*, COUNT(entries.id) AS number_of_applicants")
  .group("programs.id")

Specify the name of the association in the joins argument. It is not a table name. In the argument of select method, specify the column to get the value from the table. The SQL function COUNT returns the number of records for which the value of the column specified in the argument is not NULL. Since AS names the value on the left side, you can get the number of records in the entries table as a column called number_of_applicants. The group method divides the records into groups based on the column specified in the argument. If you specify an aggregate function such as COUNT in select, you must call it in principle. By dividing into groups, you can get the number of entries for each program_id.

program[:number_of_applicants]

You can refer to it as above.

Left outer join of table

When you join tables with the joins method normally, records that are not referenced at all from the joined table will be excluded from the search results. In other words, only programs for which one or more applications have been submitted will be searched.

left_joins(:entries)

If you rewrite joins with left_joins, unreferenced records will remain.

Continued

We will add the URLs of the following articles one by one.

Ruby on Rails6 Practical Guide [Extensions] cp7 ~ cp9 [Memo] Ruby on Rails6 Practical Guide [Extensions] cp10 ~ cp12 [Memo]

Quote source

Recommended Posts

Ruby on Rails6 Practical Guide [Extensions] cp7 ~ cp9 [Memo]
Ruby on Rails6 Practical Guide [Extensions] cp10 ~ cp12 [Memo]
Ruby on Rails6 Practical Guide [Extensions] cp3 ~ cp6 [Memo]
Ruby on Rails6 Practical Guide cp13 ~ cp15 [Memo]
Ruby on Rails6 Practical Guide cp7 ~ cp9 [Memo]
Ruby on Rails6 Practical Guide cp4 ~ cp6 [Memo]
Ruby on Rails6 Practical Guide cp10 ~ cp12 [Memo]
Ruby on Rails6 Practical Guide cp16 ~ cp18 [Memo]
Ruby on Rails 6.0 environment construction memo
[Ruby on Rails] Select2 introduction memo for Webpacker
[Personal memo] Ruby on Rails environment construction (Windows)
Ruby on Rails Elementary
Ruby on Rails basics
Ruby On Rails Association
Ruby on Rails5 Quick Learning Practice Guide 5.2 Compatible Chapter2
Ruby on Rails5 Quick Learning Practice Guide 5.2 Compatible Chapter3
Ruby on rails learning record -2020.10.03
Portfolio creation Ruby on Rails
Ruby on rails learning record -2020.10.04
[Ruby on Rails] Debug (binding.pry)
Ruby on rails learning record -2020.10.05
Ruby on rails learning record -2020.10.09
Ruby on Rails config configuration
Ruby on Rails basic learning ①
[Ruby on Rails] about has_secure_password
Ruby on rails learning record-2020.10.07 ②
Commentary on partial! --Ruby on Rails
Ruby on rails learning record-2020.10.07 ①
Cancel Ruby on Rails migration
Ruby on rails learning record -2020.10.06
Ruby on Rails validation summary
Ruby on Rails Basic Memorandum
Ruby on Rails Overview (Beginner Summary)
[Ruby on Rails] Read try (: [],: key)
[Ruby on Rails] yarn install --check-files
Ruby on Rails variable, constant summary
Installing Ruby + Rails on Ubuntu 18.04 (rbenv)
[Ruby on Rails] Introduced paging function
Basic knowledge of Ruby on Rails
Progate Ruby on Rails5 Looking Back
How to use Ruby on Rails
[Ruby on Rails] Add / Remove Columns
Ruby on Rails Japanese-English support i18n
(Ruby on Rails6) "Erase" posted content
[Ruby on Rails] CSV output function
[Ruby on Rails] What is Bcrypt?
[Ruby on Rails] Confirmation page creation
Ruby On Rails devise routing conflict
[Ruby on Rails] Comment function implementation
[Ruby on Rails] DM, chat function
[Ruby on Rails] Convenient helper method
[Ruby on Rails] Stop "looping until ..."
[Ruby on Rails] Search function (not selected)
[Rails] Addition of Ruby On Rails comment function
[Ruby on Rails] Creating an inquiry form
[Ruby on Rails] View test with RSpec
[Ruby on Rails] How to use CarrierWave
[Ruby on Rails] Code check using Rubocop-airbnb
[Ruby on Rails] 1 model CRUD (Routing Main)
Ruby on Rails installation method [Mac edition]
[Ruby on Rails] model, controller terminal command