Ruby on Rails6 Practical Guide cp13 ~ cp15 [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. It is divided into 18 chapters, so 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]

Chapter 13 Associations between models

Switch processing depending on whether resources are nested

routes.rb


resources :staff_members do
  resources :staff_evnets, only: [ :index ]
end
resources :staff_events, only: [ :index ]

When the above routing is set,

staff_events_controller.rb


def index
  if params[:staff_member_id]
    @staff_member = StaffMember.find(params[:staff_member_id])
    @events = @staff_member.events.order(occurred_at: :desc)
  else
    @events = StaffEvent.order(occurred_at: :desc)
  end
end

You can switch the process depending on whether the URL path includes staff_member_id. The same action can be used for both specific employee events and all events.


render collection

= render partial: "event", collection: @events

If you specify an array for the collection option of the render method in the template and call it, the partial template will be embedded repeatedly as many times as there are elements in the array.

I investigated in detail and wrote an article. Implementing iteration in View by rendering collection [Rails]


N + 1 problem

It is called N + 1 problem </ strong> that the number of queries is issued by adding 1 to the number of objects you want to get even though you can reduce the number of queries.

includes

@events = @events.includes(:member)

If you give the name of the association to the includes method, a query will be issued to get the associated model objects in bulk. The result is fewer queries issued, which often leads to better performance.

Chapter 14 Value Normalization and Validation

Value normalization

Method for normalization

models/concern/string_normalizer.rb


require "nkf"

def normalize_as_text(text)
  NKF.nkf("-W -w -Z1", text).strip if text
end

def normalize_as_furigana(text)
  NKF.nkf("-W -w -Z1 --katakana", text).strip if text
end

The NKF module provides Japanese-specific conversion functions. The nkf method takes a flag string as the first argument and a string to be converted as the second argument, and returns the converted string.

flag meaning
-W Input character code is UTF-Specify to be 8
-w UTF-Output at 8
-Z1 Convert full-width alphanumeric characters, symbols, and full-width spaces to half-width
--katakana Convert Hiragana to Katakana

Flag string list

Flag strings can be written concatenated.

NKF.nkf("-WwZ1", text)

The strip method strips blank strings at the beginning and end of the string.

before_vallidation

The process that is executed before and after the operation such as validation, save, and deletion of the model object is called callback </ strong> or hook </ strong>. before_validation is executed just before validation.

before_validation do
  self.family_name = normalize_as_name(family_name)
  self.family_name_kana = normalize_as_furigana(family_name_kana)
end

In the example above, the name and frigana are normalized before validation is performed.


Gem data-validaor

data-validator provides data type validation.

option What to check
after After the specified date. However, the specified date is not included.
before Before the specified date. However, the specified date is not included.
after_or_equal_to After the specified date. However, it includes the specified date.
before_or_equal_to Before the specified date. However, it includes the specified date.
allow_blank If you do true, blanks are allowed
before: -> (obj) { 1.year.from_now.to_date }

For date type validation, you can specify a base date dynamically by specifying a Proc object.

before: 1.year.from_now.to_date

It works even if you write it as above, but it causes unexpected results because the value of the before key is fixed based on the startup time.


validate

validate do
  unless Staff::Authenticator.new(object).authenticate(current_password)
    errors.add(:current_password, :wrong)
  end
end

validate is used to implement validation in ways other than built-in validation.

Chapter 15 Presenter

What is a presenter?

The class responsible for generating the HTML code associated with an object is called a presenter </ strong>. It's not an official Rails term, but a concept born within the Rails community.


Model presenter

Presenter when the target is a model object.

app/presenters/model_presenter.rb


class ModelPresenter
  attr_reader :object, :view_context

  def initialize(object, view_context)
    @object = object
    @view_context = view_context
  end
end

Define a StaffMemberPresenter class that inherits from the ModelPresenter class.

staff_member_presenter.rb


class StaffMemberPresenter < ModelPresenter

  #Employee stop flag on/Returns a symbol that represents off
  def suspended_mark
    object.suspended? ?
      view_context.raw("&#x2611;") :
      view_context.raw("&#x2610;")
  end
end

Usage example </ strong>

ruby:staff_members/index.html.haml


- @staff_members.each do |m|
  - p = StaffMemberPresenter.new(m, self)
  - p.suspended

I am creating an instance of StaffMemberPresenter. StaffMember object is specified as the first argument and self is specified as the second argument. The object referenced by self in the view template is called the view context </ strong>. This object has all the helper methods defined in Rails as its own methods.


transfer

Delegation allows you to write your code concisely.

model_presenter.rb


  delegate :raw, to: :view_context

staff_member_presenter.rb


  delegate :suspended?, to: :object

The delegate method defines an instance method with the name specified in the argument and delegates it to the object returned by the method specified in the to option.

In short, you can omit the receiver when calling the method. As a result of defining delegate, it is now possible to write concisely as below.

staff_member_presenter.rb


  def suspended_mark
    suspended? ? raw("&#x2611;") : raw("&#x2610;")
  end

We will omit the HtmlBuilder module and form presenter.


Continued

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

Ruby on Rails6 Practical Guide cp16 ~ cp18 [Memo] 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