Ruby on Rails6 Practical Guide cp16 ~ cp18 [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. Since it is divided into 18 chapters, we will divide it by heading.

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]

Chapter 16 Single Table Inheritance

Single Table Inheritance </ strong> is a way to simulate the concept of inheritance in object-oriented programming in a relational database.

Single table inheritance allows you to record multiple types of similar objects together in a single table.

If you have a table called address with a string type column and a postal_code column, you can express single table inheritance by defining it as follows:

class Address < ApplicationRecord
end

class HomeAddress < Address
end

class WorkAddress < Address
end

The HomeAddress and WorkAddress classes inherit from the Address class. At this time, you can save the HomeAddress and WorkAddress objects in the database as follows:

HomeAddress.create(postal_code: "1000001")
WorkAddress.create(postal_code: "1000002")

This information is recorded in the Address table as shown in the table below.

id type postal_code
1 HomeAddress 1000001
2 WorkAddress 1000002

Rails automatically sets the value in the type column.

Also, the code to get the HomeAddress and WorkAddress objects from the database looks like this:

a1 = HomeAddress.find(1)
a2 = WorkAddress.find(2)

The id value must correspond to the class name in the type column.


fields_for

= form_with model: @customer_form do |f|
  = f.fields_for :customer, f.object.customer do |ff|
  -#abridgement

You can use the form builder instance method fields_for to switch the target object of the form. You can generate forms for multiple model objects with the same form. The record name is the first argument and the target object is the second argument.


When to save the associated object

If the Cusotmer object is associated with a HomeAddress object and a WorkAddress object,

customer.save
customer.home_address.save
customer.work_address.save

Saving a Cusotmer object does not automatically save the HomeAddress object.

However, if the Cusomer object is not saved in the database, the HomeAddress and WorkAddress objects are automatically saved as well.

transaction

ActiveRecord::Base.transaction do
  customer.save!
  customer.home_address.save!
  customer.work_address.save!
end

Enclosed in an ActiveRecord :: Base.transaction block, this range of database processing is executed as a transaction.

Chapter 17 Capybara

let!

let(:staff_member) { create(:staff_member) }
let!(:staff_member) { create(:staff_member) }

The let method creates and stores an object the first time it is called, and returns the same result the second time. The let! method differs in that it creates an object at definition time.


inclusion

validates :gender, inclusion: { in: %w(male female), allow_blank: true }

inclusion ensures that the value is in a particular list.


Validate multiple objects at the same time

def valid?
  customer.valid? && customer.home_address.valid?
    && customer.work_address.valid?
end

When dealing with multiple objects in one form, checking the validation as above causes problems. If the customer object fails validation, it will return false at that point, so home_address and work_address validation will not be checked. As a result, the error cannot be displayed on the form.

def valid?
  [ customer, customer.home_address, customer.work_address ]
    .map(&:valid?).all?
end

If you make an object into an array and call valid? For each using map, the result will be returned as an array. The all? method is a method that verifies whether all the elements of the array are true. You can now check the validation of all objects.


autosave

class Customer < ApplicationRecord
  has_one :home_address, dependent: :destroy, autosave: true
  has_one :work_address, dependent: :destroy, autosave: true
end

If you specify true for the autosave option, the associated object will also be saved automatically.


Share normalization and validation

You can share your code with ActiveSupport :: Concern. ActiveSupport :: Concern is also written in Articles in the previous chapter.

app/models/concerns/email_holder.rb


class EmailHolder
  extend ActiveSupport::Concern

  included do
    include StringNormalizer
     
     before_validation do
       self.email = normalize_as_email(email)
     end

     validates :email, presence: true, "valid_email_2/email": true,
        uniqueness: { case_sensitive: true }
  end
end

StringNormalizer is a module for normalization created in the previous chapter. valid_email_2 / email is a gem that adds validation of email addresses.

#Include in your model
include EmailHolder

Chapter 18 Form Objects

mark_for_destruction

customer.home_address.mark_for_destruction

Calling the mark_for_destruction method on the associated model object will mark it for deletion. The deletion target is deleted when the parent is saved in the database. In the above example, the deletion target is home_address and the parent is customer. For this mechanism to work, you must specify true for the associated autosave option.


Scope of association

has_many :personal_phones, -> { where(address_id: nil).order(:id) },
  class_name: "Phone", autosave: true

You can indicate the scope of the association by specifying a Proc object as the second argument of has_many.


index

= form_with model: @customer_form, scope: "form" do |f|
  = customer.perdonal_phones.each_with_index do |phone, index|
    = f.fields_for :phones, phone, index: index do |ff|
      = f.text_field :number

When creating multiple forms of the same object, you can identify them with the index option. By adding the index option, the name attribute of the input element changes. In the above example, it would be form [customer] [phones] [0] [number].

Continued

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

Ruby on Rails6 Practical Guide [Extensions] cp3 ~ cp6 [Memo] 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 cp13 ~ cp15 [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 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 Rails Elementary
Ruby On Rails Association
[Ruby on Rails] Select2 introduction memo for Webpacker
[Personal memo] Ruby on Rails environment construction (Windows)
Ruby on rails learning record -2020.10.03
Portfolio creation Ruby on Rails
Ruby on rails learning record -2020.10.04
Ruby on Rails5 Quick Learning Practice Guide 5.2 Compatible Chapter2
[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 Rails5 Quick Learning Practice Guide 5.2 Compatible Chapter3
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
[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 memo
[Ruby on Rails] Introduction of initial data
[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] 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
Let's summarize "MVC" of Ruby on Rails
Ruby on Rails model creation / deletion command
[Ruby on Rails] About bundler (for beginners)