はじめに
この記事の筆者はプログラミングを学習し始めたばかりの初心者です。間違いがあれば指摘していただけると幸いです。
概要
この記事はRuby on Rails6 実践ガイドを読んで学んだことを自分用のメモとして記録したものです。抜粋してピックアップするので読みづらいと思われます。すいません。
この本には、続編の機能拡張編もあり、記事を書いている段階で二冊とも学習を終えています。復習もかねて記事を書いていくつもりです。
18のチャプターに分かれているので、見出しごとに区切っていきます。
前の記事
Ruby on Rails6 実践ガイド cp4~cp6 【メモ】
Ruby on Rails6 実践ガイド cp7~cp9 【メモ】
Ruby on Rails6 実践ガイド cp10~cp12 【メモ】
Chapter 13 モデル間の関連付け
リソースがネストされているかどうかで処理を切り替える
resources :staff_members do
resources :staff_evnets, only: [ :index ]
end
resources :staff_events, only: [ :index ]
上のようなルーティングが設定されている時、
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
URLパスにstaff_member_idが含まれるかどうかで処理を切り替えることができます。特定の職員のイベントの場合とすべてのイベントの場合のどちらも同じアクションで処理することができます。
render collection
= render partial: "event", collection: @events
テンプレート内でrenderメソッドのcollectionオプションに配列を指定して呼び出すと、配列の要素の数だけ部分テンプレートが繰り返し埋め込まれます。
詳しく調べて記事を書きました。
Viewでの繰り返しをコレクションをレンダリングすることで実装する【Rails】
N+1問題
クエリの回数を減らせるにもかかわらず、取得したいオブジェクトの個数に1を加えた回数のクエリが発行されてしまうことをN+1問題といいます。
includes
@events = @events.includes(:member)
includesメソッドに対して関連付けの名前を与えると、関連付けられたモデルオブジェクトを一括して取得するクエリが発行されるようになります。
その結果、発行されるクエリの回数が減り、多くの場合でパフォーマンスの向上につながります。
Chapter 14 値の正規化とバリデーション
値の正規化
正規化のためのメソッド
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
NKFモジュールは日本語特有の変換機能を提供します。nkfメソッドは第一引数にフラグ文字列、第二引数に変換対象の文字列をとり、変換後の文字列を返します。
フラグ | 意味 |
---|---|
-W | 入力の文字コードがUTF-8であることを指定 |
-w | UTF-8で出力する |
-Z1 | 全角の英数字、記号、全角スペースを半角に変換する |
--katakana | ひらがなをカタカナに変換する |
フラグ文字列は連結して書くことができます。
NKF.nkf("-WwZ1", text)
stripメソッドは文字列の先頭と末尾にある空白文字列を除去します。
before_vallidation
モデルオブジェクトに対してバリデーション、保存、削除などの操作が行われる前後に実行される処理をコールバックまたはフックといいます。
before_validationはバリデーションの直前に実行されます。
before_validation do
self.family_name = normalize_as_name(family_name)
self.family_name_kana = normalize_as_furigana(family_name_kana)
end
上の例では、バリデーションが実行される前に名前とフリガナに対して正規化を行っています。
Gem data-validaor
data-validatorはdataタイプのバリデーションを提供します。
オプション | チェックする内容 |
---|---|
after | 指定された日付より後。ただし、指定された日付は含まない。 |
before | 指定された日付よりも前。ただし、指定された日付は含まない。 |
after_or_equal_to | 指定された日付よりも後。ただし、指定された日付を含む。 |
before_or_equal_to | 指定された日付よりも前。ただし、指定された日付を含む。 |
allow_blank | trueをしてすれば空欄が許可される |
before: -> (obj) { 1.year.from_now.to_date }
dateタイプのバリデーションでは、Procオブジェクトを指定すると動的に基準となる日付を指定することができます。
before: 1.year.from_now.to_date
上のように書いても動きますが、beforeキーの値が起動時を基準にして固定されてしまうので、予想外の結果を引き起こします。
validate
validate do
unless Staff::Authenticator.new(object).authenticate(current_password)
errors.add(:current_password, :wrong)
end
end
validateは、組み込みバリデーション以外の方法でバリデーションを実装するときに利用します。
Chapter 15 プレゼンター
プレゼンターとは
あるオブジェクトに関連するHTMLコードを生成する役割を担うクラスをプレゼンターと呼びます。
Railsの公式用語ではなく、Railsコミュニティの中で生まれた概念です。
モデルプレゼンター
対象がモデルオブジェクトの場合のプレゼンターです。
class ModelPresenter
attr_reader :object, :view_context
def initialize(object, view_context)
@object = object
@view_context = view_context
end
end
ModelPresenterクラスを継承したStaffMemberPresenterクラスを定義します。
class StaffMemberPresenter < ModelPresenter
# 職員の停止フラグのon/offを表現する記号を返す
def suspended_mark
object.suspended? ?
view_context.raw("☑") :
view_context.raw("☐")
end
end
使用例
- @staff_members.each do |m|
- p = StaffMemberPresenter.new(m, self)
- p.suspended
StaffMemberPresenterのインスタンスを作成しています。第一引数にStaffMemberオブジェクト、第二引数にselfを指定しています。
ビューテンプレート内でselfによって参照されるオブジェクトをビューコンテキストと呼びます。このオブジェクトはRailsで定義されたすべてのへルパーメソッドを自分のメソッドとしてもっています。
委譲
委譲を用いるとコードを簡潔に書くことができます。
delegate :raw, to: :view_context
delegate :suspended?, to: :object
delegateメソッドは引数に指定された名前のインスタンスメソッドを定義し、toオプションに指定されたメソッドが返すオブジェクトに委ねます。
要するにメソッドを呼び出すときにレシーバーを省略できるようになります。
delegateを定義した結果、下のように簡潔に書くことができるようになりました。
def suspended_mark
suspended? ? raw("☑") : raw("☐")
end
HtmlBuilderモジュールとフォームプレゼンターについては省略します。
続き
続きの記事のURLも順次追加していきます。
Ruby on Rails6 実践ガイド cp16~cp18 【メモ】
Ruby on Rails6 実践ガイド[機能拡張編] cp3~cp6 【メモ】
Ruby on Rails6 実践ガイド[機能拡張編] cp7~cp9 【メモ】
Ruby on Rails6 実践ガイド [機能拡張編] cp10~cp12 【メモ】
引用元
※マークダウンの引用を用いている部分は以下の書籍から引用しています。
Ruby on Rails6 実践ガイド