The author of this article is a beginner just starting to learn programming. I would appreciate it if you could point out any mistakes.
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]
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.
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.
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.
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
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.
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].
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]
Recommended Posts