part1:overview
ルーティング情報ファイルについて
config/routes.rb
でモデルに対して CRUD 操作を定義している。
# config/routes.rb Rails.application.routes.draw do resources :books end
resources :books
の部分で、 CRUD 操作を定義している。resources
メソッドに :books
を渡すことで CRUD 操作用のルーティングが設定される。
Active Recordとは
Active Record の理解が甘かったので、『Active Record の基礎 - Railsガイド』と、『パーフェクト Ruby on Rails』で内容を確認。
Active Recordとは、MVCで言うところのM(モデル)で、ビジネスデータとビジネスロジックを表すシステムの階層のことを言う。
Active Record の目的は、データベースに恒久的に保存される必要のあるビジネスオブジェクトの作成と利用を円滑に行えるようにすること。
Active Record は、『Patterns of Enterprise Application Architecture』という書籍にデザインパターンとして記されている。そこでは、『データアクセスのロジックを常にオブジェクトに含めておき、そのオブジェクトの利用者にデータベースへの読み書き方法を指示できるようにする』としている。
Active Record には多くの機能があるが、大きく2つの役割がある。
- データベースと接続し、データベースのレコードと ActiveRecord オブジェクトを結びつける
- バリデーションやレコード保存時などに実行する様々なコールバックなどを実行する
バリデーション(検証)とは
バリデーションは、Active Record を使って、モデルがデータベースに書き込まれる前に、モデルの状態を検証(バリデーション)することを言う。
Active Record にはモデルチェック用の様々なメソッドが用意されている。例えば、次のようなものがある。
- 属性が空でないかどうか
- 属性が一意かどうか
- 既にデータベースにないかどうか
- 特定のフォーマットに沿っているかどうか
『属性が空でないか』のバリデーションは、次のように書ける。下記は User
モデルの name
属性が空でないかを検証する。
class User < ApplicationRecord validates :name, presence: true end
注意としては、レースコンディションですり抜けてしまう問題もあり得るため、データベースで not null
制約などで設定する方がベター。
コールバックとは
コールバックは、オブジェクトのライフサイクル期間における特定の瞬間に呼び出されるメソッドのこと。
コールバックを利用することの旨味は次のもの。
- 前処理、後処理などを宣言的に書ける
- 保存後に必ず実行したい処理があるときに、実行漏れを防げる
つまり、コールバックは、オブジェクトの状態が切り替わる『前』または『後』に宣言したロジックをトリガする。
コールバックを利用する際の流れを次に示す。
コールバックを登録する
下記の
before_validation
がコールバックとなっていて、バリデーションの前に、before_validation
として登録されたensusure_login_has_a_value
メソッドをトリガする。class User < ApplicationRecord validates :login, :email, presence: true before_validation :ensure_login_has_a_value private def ensure_login_has_a_value if login.nil? self.login = email unless email.blank? end end end
コールバックをトリガする
コールバックの実行は、以下のメソッドを実行することによりトリガされる。
- create
- create!
- destroy
- destroy!
- destroy_all
- destroy_by
- save
- save!
- save(validate: false)
- toggle!
- touch
- update_attribute
- update
- update!
- valid?
after_find
コールバックは以下のfinder
メソッドを実行すると呼び出される。- all
- first
- find
- find_by
- find_by_*
- find_by_*!
- find_by_sql
- last
ビューのレンダリング
コントローラでモデルからデータ抽出や加工を行い、ビューでコントローラで取得したデータをユーザが認識可能な形式にレンダリングする。
レンダリングでは、render
メソッドを使うことで、コントローラとビューを結びつける。
class BooksController < ApplicationController before_action :set_book, only: %i[show edit update destroy] ... # レンダリングを明示的に書く場合 def show render :show end # レンダリングを暗黙的に書く場合 def show; end # => 『render アクション名(show)』と解釈される ... def set_book @book = Book.find(params[:id]) end ...
render :show
の部分でレンダリングをしており、具体的には以下のことをする。
描画するためのテンプレートを探索
探索は、
RAILS_ROOT/app/views/コントローラ名/アクション名.html.erb
に対して行われる。拡張子は使用するテンプレートエンジンによって異なる。- 見つかったテンプレートを基に、データを展開し最終的なHTMLを生成
上記の例では、ビューに渡すデータを before_action
にて値をセットすることで、各ビューでデータを扱えるようにしている。