『パーフェクトRuby on Rails』学習メモ

Part1 Rails overview

Ch01 Ruby on Railsの概要

  • Rakefile
    • rake -T : タスク一覧
    • rake (taskname) : タスク実行
  • bundle
    • gem packageを束ねる
    • Gemfileが作られる.
  • Railsの思想
    • Web application開発のためのframework
    • CoC(Convention over Configuration)
      • 設定より規約
      • 規約により設定が不要になる.
    • DRY
    • REST(REpresentational State Transfer)
      • すべてのリソースに一意となる識別子(URI)があるという思想.
      • URIを通してリソースを操作する手段を提供
      • リソースを操作するための動詞を中心に考え,機能追加しやすい自然な設計にする
    • 自動テスト
    • まとめ
      • Web applicationをRailsが語る思想に沿ったarchitectureで作成することを,The Rails Way, レールに乗ると表現する.
  • Railsをはじめよう
    • rails new (project name)
      • 重要なファイルなど
    • binstubファイルとして,binにbundle exec省略可能なコマンドを置いている.
    • MVC architectureとして,appディレクトリ以下にmodels, views, controllers + Viewで使うhelpers + assets for frontend + others
    • rails s: Web applicationを起動. s: server
    • libは,独自に実装したRakeタスクなどを配置するのみ.かつては,独立性の高いコードを置く運用もあった.
    • よく使うrailsコマンド
      • routes: display routing information
      • runner: 処理を明確にするため,Rakeとは個別のコマンドとして用意された単体スクリプトの実行
  • scaffold(足場)
    • CRUD操作を行うMVCそれぞれのコードと,テストやDBのテーブル定義を行うmigration fileなどを生成.
    • project作成→scaffold実行
    • DBの変更をmigrationファイルで管理
    • routesでURL設計を確認.
    • RESTfulな考え方がベースとなり作られる.
    • controller, routing
    • routingでURLとコントローラ内のメソッドを紐づけることでURLに対応するアクションを定義.アクションの中で,モデルを通じてデータを取得.そのデータをもとにテンプレートファイルを通じてHTMLを作成・描画している.

Ch02 Ruby on RailsMVC

目的

  • MVCの各要素に対してどのようなコードを書けばよいか見る.
  • MVCのそれぞれの基本的な機能を学ぶ.

内容

  • MVC architecture
    • Model
    • View
      • Modelの内容を参照し,視覚表現を行う
    • Controller
      • Modelのロジック呼び出し,必要なViewの選択など,ModelとViewをつなぐ部分
    • モデルの基礎と考え方
      • modeling: システムを作ることは,解決する問題に対して必要な概念を探して,命名・関係性の整理を行うこと.
      • ActiveRecordでのmodelのimplementation
      • modelとCRUDとの対応.
  • modelを扱う
    • modelを通じた検索
      • ActiveRecord::Relationクラスについて
        • ActiveRecordのQuery Interfaceによる操作結果をオブジェクトとして表現するもの
        • SQLの情報を保持し,実際に必要になったときのみDBにアクセス.
          • 明示的にSQLを発行するときは,to_a method
        • Scopeで,よく使う検索条件をまとめて命名
          • nilを返す必要があるときはクラスメソッドで定義する方が〇
        • default_scopeは安易には使えない
    • model同士のrelation
      • 関連付け
        • SQLite3のための対応必要.
      • has_many, has_one, belong_to
      • 多対多
        • 中間テーブルが必要.
    • dataの更新
      • create, save
      • validation
      • !をつけるとvalidation失敗時に例外発生
    • callback
      • callbackpoint
    • enum
      • !, ?
  • controllerの役割
    • hook
    • CSRF(Cross Site Request Forgeries)対策
    • resources routing
    • exception
      • rescue_from
    • StrongParameters
      • Mass Assignmentで利用できるHashのkeyの許可リストを定義する
      • 権限の扱いなど
  • controllerとviewの協調と,view templateの基本
    • renderingまでの流れ
    • contentsのtypeに合わせる
      • respond_to
    • redirect_to
    • 部分テンプレート, layout
      • variantsによるtemplateの切り替え
  • about view template
    • Prefixの値 + _path で,routingで定義したpathを取得できる
    • helper methodの活用例
      • url_for
      • link_to
      • form_with
      • stylesheet_link_tag, javascript_pack_tag
      • その他
      • 独自メソッド定義
        • app/helpers
    • escape 処理
      • XSS対応
        • そのまま表示 → raw
    • template engine
      • ERB
        • \%を使ってRubyのコードを評価
      • Haml
        • indentでHTMLの構造を表現できる
        • gem packageとして取得する
      • Slim
    • API server として振る舞うときのviewについて

まとめ

  • Model層について,ActiveRecordの基本的な操作,validation,callback
  • Controller層について,ModelとViewをつなぐこと,request objectやaction callback,脆弱性への対処
  • View層について,受け取ったModelを表示すること,template engine, helper method,様々なformatでの表示

  • applicationの主要なlogicはなるべくModelに書くべき

    • Fat Modelへの対応必要.
  • API専用のRails application

    • frontendのimportance高まり,描画を完全にJSに任せるケースあり.
    • rails new my_api --api

Ch03 Railsのbasic機能

  • testの種類と実行方法
    • 各ファイル・ディレクトリごとにテスト対象がある.
    • testの実行
      • bin/rails test (-v)
      • directory単位,ファイル単位,特定の行,テスト名の指定ができる
    • minitestをRailsで扱う
    • fixtureでテストデータを定義
      • modelname(:fixturename)
    • setup, teardown
    • Rails 6.0から,並列テスト可能になる
      • test/test_helper.rb
        • parallelize(workers: 1)とすると並列度が1になる
        • with::threadsとすると,processでなくthreadで並列実行できる
  • RackとRailsの関係
    • Rack: Web application serverとWeb application frameworkの中間において,interfaceを共通化した仕様・実装
      • 疎結合なやり取りを行えるようにするもの
    • Rack application: call methodから受け取ったHTTP request dataなどを元にresponceとして返す内容を決定し,call methodの戻り値とするもの
    • Rack middleware
      • middlewareは,initializeで後続として処理していくapplication(or middleware)のオブジェクトを受け取り,自身のcall methodが呼ばれたときにinitializeで受け取ったオブジェクトのcall methodを呼ぶことで,後続処理を行うという流れ.
      • Pylonsの説明にある玉ねぎの図
      • config内で,使用の有無を管理
        • middlewareの上下関係の設定もできる
  • DBの管理
    • DB関連task
      • RAILS_ENV=productionで製品環境を指定できる
    • 定義の反映
      • db:rollback STEP=1
    • schema fileの取り扱い
    • 用意したデータを読み込む
      • db/seeds.rb
      • !をつけて,エラー発生にすぐに気づけるようにする.
    • table stateを扱う
      • reset = drop + setup
      • prepare: migration, or setup
    • 複数DBを扱う
      • config/database.yml
      • --database=sub
      • 書き込みと読み込みの分離
        • config/environments/production.rb
  • 秘密情報の管理
    • versionごとに管理方法が異なる
    • より開発プロセスにあった形になっている.
  • HTTPとRails application
    • Early Hints
      • 200 OKの前に,103 Early Hints
        • HTMLのパース中にアセットのロード可能
    • CSP(Contents Security Policy)
      • config/initializers/content_security_policy.rb
      • nonce
      • strict-dynamic

Part 2 Railsの周辺知識

Ch04 frontendの開発手法

  • Railsで利用するエコシステムの軸をfrontend開発の標準的な仕組みに移している.
  • JSを管理
    • CSSや画像の管理
    • 自動ビルド
    • ビルド方法の切り替え
    • libraryの統合
    • plugin, loaderの追加
  • CSSの管理
    • CSSを拡張した言語をCSSコンパイル,リクエスト数削減のために1つのファイルへ結合する処理など.
    • 本番環境向けビルド
      • file size削減
    • JSの機能 built in Rails
      • 画面の制御
      • Ajax通信
      • 画面遷移の高速化
        • body tagの中身を入れ替える
        • event の発火
        • Turbolinks
  • 控えめなJS framework
    • Stimulus: 規約をもたらすframework
      • server sideにbusiness logicの実装が寄る
        • HTMLはサーバから返す
        • server sideとfrontendを合わせたトータルの工数が少ない
        • frontendで表現できる幅が狭まる

Ch05 Rails標準の機能を活用して素早く機能実装する

  • Active Jobによる非同期実行
    • mail sending, data集計→CSVファイル作成などの時間がかかる処理に使う
    • 実装,キュー,引数,バックエンドの設定,複数キューの管理,ジョブの例外処理,ジョブのテスト
  • Active Storageによるファイルアップロード
    • 動作,設定
    • サムネイルの生成
    • access制限
    • direct upload
    • helperの不足
    • cacheの不足
  • Action Mailerによるメール送信
    • 使い方,動作確認
    • 設定
    • test
  • Action Mailerによるメール受信
    • 対応サービス
    • 事前準備
    • projectの作成
    • 処理の流れと実装手順
    • test
  • Action TextによるRich text 機能
    • 使い方
    • N+1問題
    • customize
  • Action Cableによるreal time通信
    • web socketを使ったリアルタイム処理
    • chat serviceの作成
    • config
    • 認証
    • worker数の設定
    • UT

Part3 Web Application development

Ch06 Rails application development

  • Railsの機能をいつどのように使うか,一般的なWeb applicationを開発する際に気を付けるべきポイントを見る
  • event notify applicationを作る
  • applicationの作成と下準備
    • applicationの作成
    • Hamlの導入
    • 独自のtop pageの表示
      • top page用のcontrollerの作成
    • gemのversion up 戦略について
    • Bootstrapの導入
      • CSSの記述を最小限にしつつ,デザインを調整しながら開発できるようにする
  • OAuthを利用して「GitHubでログイン」機能を作る
    • GitHub applicationの登録
    • ログインのための機能の作成
    • user model作成
    • ログイン処理の作成
    • ログアウト処理の作成
  • event registration機能の作成
    • time zoneの設定
    • event用のmodelの作成
      • 文字数の制限
        • 正しいデザインで表示するため
    • ログイン状態を管理する処理の作成
    • event registration用のフォームの作成
    • validation error時の設定
      • SJR(Server-generated JS Responses)
    • i18nの設定をする
  • eventの閲覧機能を作る
    • l: localize
  • eventの編集・削除機能を作る
    • 関連を利用する
  • 登録されたeventへの参加機能,参加キャンセル機能を作る
    • N+1問題
    • helperの使い方.オブジェクト指向的な書き方にならない.多いときはプレゼンター.
    • 必ずredirect→インスタンス変数をビューに渡す必要なし→インスタンス変数を使わず可読性を上げる
    • has_manyにdependent: :destroyで,親オブジェクトのレコード削除時に子のレコードも削除.
  • 退会機能を作る
    • 基本の7つ以外のアクションを作りたくなったら別のコントローラを作る.
  • おわりに
    • なぜこのような機能があるのかが重要

Ch07 Rails applicationの test

  • test codeをどう書いていくか
    • システムテストから書く
      • reasons
        • 概要をつかんだ時点でテストを書き始められる
        • すべてを通るのでカバレッジを効率よく広げられる
        • applicationに対する理解が深まる
      • problems
        • ブラウザを使うためスピード遅い
        • モデルなどの部品ごとの仕様の検証は不可能
  • minitest, RSpec
  • test data作成
    • factory_bot
      • sequenceで,固定値を回避
      • 乱数を同じにする場合はseedをオプションで指定する.
  • system test
    • 環境の問題の解決が必要@wsl2
  • controller test
  • model test
    • stub, mock
    • ランダムな値で都合のいいデータを回避
    • validationのテストの扱い

Part4 Rails applicationの拡張・運用

Ch08 Rails application 拡張

  • file upload機能の作成
    • libvipsを使う
    • direct upload時のvalidationは注意点アリ
  • gemで機能拡張する
  • その他の機能
    • error handling
      • rescue_fromは後に登録したものから順番に判定
      • Rack Middlewareを使ったerror handling
        • 独自の例外でpublic/500.html以外を表示したい場合に設定する
        • dynamic error pageのdemerit
      • routingの制限
  • gemの選定

Ch09 コードの品質を上げる

  • CI
    • GitHub actions
      • Elasticsearchとplugin
  • gemの定期更新
    • Dependabot
  • static analysis
  • coverage測定
    • SimpleCov
    • Coveralls
  • Application Performance Measure(APM)
    • Skylight
    • rack-mini-profiler
      • localで手軽に動かせる

Ch10 containerを利用したRails applicationの運用

  • Rails applicationのinfrastructure概要
    • Infrastructure as Code → Docker
    • Disposable
  • 基本的なDocker imageの構築
  • 開発環境におけるDockerの活用
    • ホストマシン上のdirectoryをコンテナ上にマウント
    • docker-compose
  • 環境によって可変する設定値や秘匿情報の管理
  • log出力
    • stdout
    • error tracking
      • 外部サービスをuse
  • HTTP serverとの通信
    • nginxなど,速さ,扱いやすさなどで必要
    • Herokuのガイドなど
    • kubernetesについて

Part5 expert Rails

Ch11 複雑なドメインを表現する

  • architecture patternから見るRails
    • domain modelとActiveRecord
      • RailsではデータストアにRDBを想定
        • ActiveRecordというarchitecture patternを用いて,DBのレコードとオブジェクトを対応付け
    • what's ActiveRecord
    • 単一table継承
      • あるクラスから派生するすべてのサブクラスを1つのtableに対応させる
        • type columnで,各レコードがどのクラスに属するか識別
          • 扱いがほかのカラムと異なる
      • 継承の是非の検討が必要
  • value object
    • entity: 属性の値にかかわらず一意に識別
    • 値objectに切り出す
      • composed_of
  • service object
    • 複数のobjectを組み合わせて表現するとき
    • eventで表現できる場合はeventで表現する
      • test doubleを使えないdemeritあり
    • 実装rule, interface

Ch12 複雑なUCを実現

  • UCとmodel
    • UC @ Rails
      • resources methodによるresource baseのroutingが基本
        • RESTに沿ったroutingを定義
      • URLで表されるresourceをDBのtableと1対1で対応させ,これらのCRUDの操作を通じてUserとやり取り
      • 1つまたは複数のCRUD操作によって,1つのUCを構成
    • Railsのレールの正体
      • modelのCRUD操作の前後に実行される処理を追加することでUCを実現するというapproach
        • e.g. validation, callback
      • UCのlogic: 対象のUCがなければ存在しない,付随するもの
        • domain logicとは異なる
    • レールの限界
  • DBと紐づかないmodelを作る
    • UCのlogic の分離
    • ActiveModel
      • DBに紐づかないmodel
      • Attributes, Callback
      • Serialization
        • attributes
      • Validations
      • Model
        • controller, viewのメソッドでobjectを使えるようにする
  • form object
    • UC logicを実装するobject, application serviceやInteractor, にform_withとの連携に必要なIFを持たせたもの
      • Userとのやり取りに用いるformを簡単に実装できる
    • 共通のvalidation ruleの定義
  • presenter
    • view helperの問題点への対応
    • a.c.a. Decorator
    • ActiveDecorator

Ch13 複雑なデータ操作を実装する

  • Concern
    • data 操作に関するlogicの実装と関連付けの宣言を行うlayer
    • ActiveSupport::Concern
      • included, class_methods, module間の依存関係解決
    • @routing
  • Callback Object
    • 実装方針
      • 更新系はCallback Object
        • for test
      • 参照系には利用できない