はじめに
当ページは.NET(C#)やObjective-Cユーザーの筆者がRuby on Rails (Ruby)を学ぶにあたり書き起こしたものである。
執筆途中であるため、所々にTBDやTODOがある。
情報源
RubyやRuby on Railsの情報は以下から取得できる。
-
Ruby
-
Ruby on Rails
-
書籍
Rubyバージョン
Rubyは定期的にリリースされている。バージョン番号を{major}.{minor}.{build}と捉えた場合、以下の傾向が見受けられる。
- Rubyのマイナーバージョンを毎年12月25日にリリースする
- マイナーバージョンをリリース後、翌年の2月〜4月にビルドリリース {major.minor.1} をする
- マイナーバージョン毎にEOLの設定があり、およそ3.25年でEOLを迎える
バージョン履歴
バージョン | リリース日 | EOL |
3.3.0 | 2023-12-25 | TBD |
3.2.2 | 2023-03-30 | 3.2.0に同じ |
3.2.1 | 2023-02-08 | 3.2.0に同じ |
3.2.0 | 2022-12-25 | 2026-03-31(見込み) |
3.1.1 | 2022-02-18 | 3.1.0に同じ |
3.1.0 | 2021-12-25 | 2025-03-31(見込み) |
3.0.1 | 2021-04-05 | 3.0.0に同じ |
3.0.0 | 2020-12-25 | 2024-03-31(見込み) |
2.7.8 | 2023-03-30 | 2.7.0に同じ |
2.7.1 | 2020-03-31 | 2.7.0に同じ |
2.7.0 | 2019-12-25 | 2023-03-31 |
2.6.10 | 2022-04-12 | 2.6.0に同じ |
2.6.1 | 2019-01-30 | 2.6.0に同じ |
2.6.0 | 2018-12-25 | 2022-04-12 |
2.5.1 | 2018-03-28 | 2.5.0に同じ |
2.5.0 | 2017-12-25 | 2021-04-05 |
2.4.1 | 2017-03-22 | 2.4.0に同じ |
2.4.0 | 2016-12-25 | 2020-03-31 |
2.3.1 | 2016-04-26 | 2.3.0に同じ |
2.3.0 | 2015-12-25 | 2019-03-31 |
2.2.1 | 2015-03-03 | 2.2.0に同じ |
2.2.0 | 2014-12-25 | 2018-03-31 |
2.1.1 | 2014-02-24 | 2.1.0に同じ |
2.1.0 | 2013-12-25 | 2017-03-31 |
2.0.0 | 2013-02-24 | 2016-02-24 |
ライフサイクル
Rubyのメンテナンスに関するライフサイクルはRuby ブランチごとのメンテナンス状況 - ruby-lang.orgで示されている。下図は同ページから引用したもの。
開発環境
Rubyを使うために環境構築をする。
Rubyインストール
Rubyをインストールする方法はいくつかある。
-
パッケージマネージャー
- apt, homebrew, wingetなどからインストールできる。
- Installing Ruby - ruby-lang.orgが詳しい。
-
インストーラー (Windowsのみ)
- Windowsにはインストーラーが提供されている。
- RubyInstaller for Windows
- rbenv & ruby-build
- Dev Container
rbenv & ruby-build
もしも、複数のRubyのバージョンを使う可能性がある場合にはrbenvを使う手がある。 インストール方法は公式サイトに案内がある。 https://github.com/rbenv/rbenv
上記のサイトからmacOSのインストール方法を抜粋する。
|
|
Dev Container
Dev Containerを使う方法は正確にはRubyをインストールするわけではなく、 手元の開発環境にRubyを入れるDockerコンテナーを用意する方法だ。
- https://www.endpointdev.com/blog/2023/01/developing-rails-apps-in-a-dev-container-with-vs-code/
- https://dev.to/konyu/how-to-use-docker-containers-for-ruby-on-rails-development-in-visual-studio-code-23np
- https://containers.dev/guide/dockerfile
- https://containers.dev/implementors/json_reference/
- https://dev.to/imiked/starting-a-rails-app-using-vscode-containers-1gj9
- https://github.com/SeanSith/rails-with-vscode-remote-containers/blob/main/docker-compose.yml
IDE or テキストエディタ
- RubyMine
-
Visual Studio Code
- Emacs
言語基礎
print & p & puts
オブジェクトを標準出力したい場合、 print
, p
, puts
を使う。
各々、以下の違いがある。
- printは改行コードを含まない(必要な場合は明示的に付与する)
- pは改行コードを含む(出力する際、テキストがダブルクォートで包まれる)
- putsは改行コードを含む
ソースコード
|
|
結果
|
|
TODO 文字列と数値
文字列から数値へ
- 文字列が数字の場合、
to_i
メソッドを使うと integer に変換する。 - 文字列が小数点を含む数字の場合、
to_i
メソッドを使うと切り捨てで integer に変換する。 - 文字列が小数点を含む数字の場合、
to_f
で float に変換する。
|
|
数値から文字列へ
|
|
真偽値
真偽値について『プロを目指す人のためのRuby入門 改訂2版』のP36に記載がある。以下に引用する。
Rubyの真偽値は次のようなルールを持っています。
- falseまたはnilであれば偽。
- それ以外はすべて真。
TODO 配列
|
|
|
|
配列操作
https://ruby-doc.org/3.2.2/Enumerable.html
|
|
日付
Rubyの組み込みライブラリないし標準ライブラリは日付や時刻を処理する以下のクラスを提供する。
Time
|
|
ISO 8601
APIの応答など日時と時刻を併せ持つ文字列として 2017-07-21T17:32:28Z
がある。その文字列書式はISO 8601もしくはRFC 3339と呼ぶ。
書式に関しては以下を参照のこと。
RubyのTimeライブラリは iso8601 メソッドを提供する。前述のように協定世界時の値が欲しい場合は utc
メソッドと併せて使う。
|
|
|
|
以下はローカルタイムの例である。
|
|
|
|
TODO Date
TBD.
TODO 演算子
TBD.
自己代入演算子
Rubyには単項演算子のインクリメント演算子 ++
やデクリメント演算子 --
が存在しない。同様なことをするには自己代入演算子を用いる。
|
|
条件演算子 (三項演算子)
演算子の再定義 (オーバーロード)
演算子式 (Ruby 3.2 リファレンスマニュアル)によると、演算子の再定義が可能である。
以下の演算子が該当する。
|
^
&
<=>
==
===
=~
>
>=
<
<=
<<
>>
+
-
*
/
%
**
~
+@
-@
[]
[]=
`
!
!=
!~
ただし、以下の演算子は再定義が不可能である。
=
?:
..
...
not
&&
and
||
or
::a
TODO ビット演算
- 論理積
&
- 論理和
|
- 排他的論理和
^
- 右ビットシフト
>>
- 左ビットシフト
<<
- 論理反転
-
nil
|
|
nil?
Object#nil?はオブジェクトがnilのある場合に true
, それ以外の場合に false
を返す。
なお、nilオブジェクトのクラスNilClassもnil?メソッドを持つが、常に true
を返す。
サンプルコード
|
|
|
|
nil条件演算子
Ruby v2.3.0でSafe navigation operatorが導入された。RubyはNullではなくnilを扱うため、見出しはNull条件演算子ではなくnil条件演算子と記載したが、これは筆者がRubyにおけるSafe navigation operatorに当てられている和名に辿り着けなかったためにそのように勝手に呼んでいることに注意されたい。
サンプルコード
|
|
|
|
blank?
TBD.
present?
Ruby on RailsではActive Supportが真偽値を返す present?
メソッドを提供する。
以下のケースはいずれも false
を返す。それ以外は true
を返す。
nil.present? false.present? [].present? {}.present? "".present? " ".present?
try
TBD.
TODO ブロック
TBD.
TODO yield
TBD.
https://docs.ruby-lang.org/ja/3.2/doc/spec=2fcall.html#yield
制御構文
制御構文について記す。
if
unless
ifとunlessでガード節
|
|
|
|
case
caseの例を示す。 case文には break
は用いない。
|
|
|
|
for
while
whileは式が偽を返すまで繰り返し実行する。
|
|
|
|
until
untilは式が真を返すまで繰り返し実行する。
|
|
|
|
next
nextのは最も近いループで次の繰り返し処理に移る。例を示す。
continue
に近い。
|
|
|
|
メソッド
引数はメソッド名の後ろに宣言する。
|
|
引数を括弧で括らず宣言することもできる。
|
|
戻り値はメソッド内で最後に評価された式になる。メソッド内の処理が戻り値を必ず return
で渡しているとは限らない。
|
|
|
|
そのため、評価対象がない場合は戻り値は nil
になる。
|
|
メソッド内で評価したものがあっても、 return
をする際にオブジェクトを指定していない場合はメソッドは呼び出し元に nil
を返す。
|
|
戻り値のオブジェクトやクラスを明示しない1。そのため、関数の実装者と利用者は戻り値の種類は常に確認が必要である。
|
|
|
|
クラスのメソッドについてはクラスメソッドとインスタンスメソッドで取り上げる。
クラス
クラスを定義する際に必要となる知識を記す。
クラス定義サンプル
|
|
|
|
初期化
クラスのインスタンス作成時における初期化について記す。
initialize
クラスのインスタンス作成では初期化処理でクラス内の initialize
を呼ぶ。
|
|
子クラスのinitializeで super
を使い、親クラスのinitializeを呼ぶことも出来る。
|
|
複数のinitialize
1つのクラスに 複数の initialize
がある場合、最後に定義されたinitializeが使われる。
|
|
そのため、先ほどのコードで引数なしのinitializeを最後に定義した場合は実行結果に変化が出る。
|
|
変数と定数
Rubyには以下の変数と定数がある。
- ローカル変数 … 小文字またはアンダースコアから始まる識別子
- インスタンス変数 …
@
から始まる識別子 - クラス変数 …
@@
から始まる識別子 - グローバル変数 …
$
から始まる識別子 - 定数 … アルファベット大文字 ([A-Z]) で始まる識別子
公式ドキュメント
インスタンス変数
インスタンスメソッドから参照、代入が可能。クラスメソッドからは参照できない。initializeメソッドで宣言、初期化する。初期化していないインスタンス変数はnilである。
|
|
クラス変数
クラス変数は @@
から始まる識別子である。クラスの特異メソッドもしくはインスタンスメソッドから参照や代入が出来る。クラスの外から直にクラス変数を参照することはできない。
以下のサンプルコードでは @@version
がクラス変数に該当する。
|
|
次のサンプルコードはサブクラスがスーパークラスのクラス変数に影響を及ぼすことを示している。
|
|
クラスインスタンス変数
クラスインスタンス変数について以下に言及がある。
Class instance variables are directly accessible only within class methods of the class.
以下に例を示す。
|
|
|
|
『プロを目指す人のためのRuby入門 改訂2版』のP293ではクラスインスタンス変数を以下のように説明している。
クラスインスタンス変数は同名であってもスーパークラスとサブクラスで異なる変数として参照されます。
どうやら特定のクラスが持つことができる変数のようだ。
定数
定数宣言の例を以下に示す。
|
|
|
|
定数をプライベートにしたい場合は private_constant
を使う。
|
|
メソッド内で定数を宣言することはできない。
|
|
なお、Rubyの定数は再代入が可能である。
|
|
|
|
定数の再代入を止めたい場合はクラスで freeze
を使う。(要Pros/Consの検証)
|
|
|
|
TBD: 配列を定数として持つクラスの場合にfreezeの効果を検証する
クラスメソッドとインスタンスメソッド
スタティックメソッドとクラスメソッドはほぼ同義である。
|
|
プロパティ (getter/setter)
attr_accessor, attr_reader, attr_writerでプロパティ(getter/setter)とインスタンス変数を宣言できる。
|
|
継承
クラスおよびモジュールを用いた継承方法について記す。
単一継承 (クラス)
クラスの継承について記す。
次のクラス図を例にコードを起こした。
classDiagram class A { +String name +int age +run() +echo(text) } class B { +String address +run_original() +echo() } A <|-- B
super
はオーバーライドしたメソッド内から親クラスにある同名のメソッドを呼び出すことができる。
親クラスの別メソッドを呼び出した場合は NoMethodError
が発生する。
次のサンプルコードは以下の特徴がある。
- クラスBのinitializeで親クラスAのinitializeをsuperで呼び初期化している。
- クラスBはクラスAのインスタンスメソッドrunをオーバライドしている。
|
|
TODO 多重継承 (モジュール利用)
TBD.
TODO module
https://docs.ruby-lang.org/ja/latest/doc/spec=2fdef.html#module
TODO 特異クラス定義
https://docs.ruby-lang.org/ja/latest/doc/spec=2fdef.html#singleton_class
TODO 構造体クラス
Rubyの構造体はクラスのようである。 https://docs.ruby-lang.org/ja/latest/class/Struct.html
そのためRubyの構造体は値型(メモリのスタック領域を使う)なのか 参照型(メモリのヒープ領域を使う)なのかがわからない。
名前空間
クラスに名前空間を設けたい場合、モジュールが有効である。
|
|
|
|
ファイル操作
ファイルを開く
公式ドキュメント
テキストファイル
|
|
バイナリファイル
バイナリファイルの例として画像ファイルを開く。
|
|
ファイルの存在確認
File.exist?はFileText.exist?と同じである。
- File.exist? (Ruby 3.2 リファレンスマニュアル)
- FileTest.#exist? (Ruby 3.2 リファレンスマニュアル)
- FileTest.#file? (Ruby 3.2 リファレンスマニュアル)
|
|
ファイルパスの作成
|
|
JSON
https://docs.ruby-lang.org/ja/3.2/library/json.html https://docs.ruby-lang.org/ja/latest/class/JSON.html
JSONファイルを読み取るサンプル
JSONサンプル
|
|
JSONファイルを読み取るサンプル
|
|
CSV
TODO YAML
テキストエンコーディング
- class Encoding (Ruby 3.2 リファレンスマニュアル)
- String#encode (Ruby 3.2 リファレンスマニュアル)
- module Kconv (Ruby 3.2 リファレンスマニュアル)
- IO.read (Ruby 3.2 リファレンスマニュアル)
|
|
TODO スレッド
プログラム実行開始時、1つスレッドが作成され、それをメインスレッドとして用いる。
|
|
スレッドを立てるにはThread.new、Thread.startやThread.forkを使う。
|
|
async/await
言語構文にasync/awaitの定義は見受けられなかった。 サードパーティのGemパッケージにasync/awaitに関するものがある。 本ページのasync / awaitで取り上げる。
例外処理
例外のオブジェクトは以下のものがある。
- RuntimeError
- SyntaxError
- StandardError
公式ドキュメント
詳細は以下を参照のこと。
サンプルコード
クラスやメソッドの外で例外処理をする場合
|
|
クラスに定義したメソッドで例外処理をする場合
|
|
TODO 正規表現
TBD.
TODO 命名規則
TBD.
TODO ドキュメントコメント
TBD.
TODO RDOC
TBD.
TODO YARD
TBD.
HTTP
HTTPクライアント、HTTPリクエスト、HTTPレスポンスなどのオブジェクトを用いたHTTPプロトコル上のデータ送受信方法について記す。
サンプルコードは通信先にJSONPlaceholderを用いる。
net/http
Rubyは標準添付ライブラリ net/http を持つ。 同ライブラリが提供する以下のオブジェクトでデータ送受信の実装をできる。
- Net::HTTP … HTTPクライアント
- Net::HTTPRequest … HTTPリクエスト
- Net::HTTPResponse … HTTPレスポンス
公式ドキュメント
詳細は以下を参照のこと。
HTTP GETの例
以下にHTTP GETリクエストを送り、HTTPレスポンスをオブジェクトとして受け取る例を示す。
|
|
なお、URIのスキーマがHTTPSの場合はNet::HTTPのインスタンスメソッド use_ssl
を真にする必要がある。そのため、 Net::HTTP.get
でHTTPSのURIに対してリクエストを送ると、以下のように~SocketError~
が発生する。
|
|
HTTP POSTの例
以下にHTTP POSTリクエストを送り、HTTPレスポンスをオブジェクトとして受け取る例を示す。
|
|
TODO httparty
https://github.com/jnunemaker/httparty
TODO rest-client
https://github.com/rest-client/rest-client
async / await
Socketry async
-
リソース
-
チュートリアル
サンプルコード
Gemfile
|
|
sample.rb
|
|
Delayed::Job
https://www.hiroakit.com/archives/20240310/
TODO GraphQL
https://graphql-ruby.org
TODO SQL
TBD.
TODO Protocol Buffers
MessagePack - msgpack
RubyでMessagePackを使う場合はGemパッケージ msgpack
を使う。
インストール
コマンドラインでインストールする。
|
|
もしくはGemfileに書き、 bundle install
をする。
|
|
簡単な動作確認をする。
|
|
自作クラスをMessage Packにする
MessagePackはExtension types仕様があり、そこでアプリケーション固有の型について述べている。
MessagePack allows applications to define application-specific types using the Extension type. Extension type consists of an integer and a byte array where the integer represents a kind of types and the byte array represents data.
Applications can assign 0 to 127 to store application-specific type information. An example usage is that application defines type = 0 as the application's unique type system, and stores name of a type and values of the type at the payload.
ここではアプリケーション固有の型を自作クラスと呼ぶが、Gemパッケージ msgpack
もExtension typesをサポートしているため、自作クラスをMessagePackのシリアライズ、デシリアライズが出来る。
その実装方法について msgpack
のREADMEのExtension typesで言及があるが、筆者は理解が追いつかなかったため、以下にサンプルコードを用意した。
|
|
要点は以下の通りである。
MessagePack::DefaultFactory.register_type
で自作クラスを登録する。- 自作クラスには
to_msgpack_ext
とfrom_msgpack_ext
を実装する。 - シリアライズする際は
MessagePack.pack
を用いる。to_msgpack_ext
が呼ばれる。 - デシリアライズする際は
MessagePack.unpack
を用いる。from_msgpack_ext
が呼ばれる。
前述のサンプルコードは以下のコードを基に幾許かの推測を加えた。
TODO テスト
TBD.
TODO Reactive Extention - RxRuby
TBD.
TODO Dependency Injection - dry-rb
TBD.
Ruby on Rails
Ruby on RailsはModel-View-Controllerアーキテクチャのウェブアプリケーションフレームワークである。David Heinemeier Hansson氏が2005年12月にバージョン1.0をリリースした。現在の最新メジャーバージョンは7である。
TODO 活用事例
TBD.
Railsバージョン
出典: https://rubyonrails.org/category/releases
バージョン | 日付 |
7.1.2 | 2023年11月10日 |
7.1 | 2023年10月5日 |
7.0 | 2021年12月15日 |
6.1.5 | 2022年3月10日 |
6.0 | 2019年10月31日 |
5.2.7 | 2022年3月11日 |
5.0 | 2016年6月30日 |
4.0 | 2013年6月25日 |
3.0 | 2010年8月29日 |
2.0 | 2007年12月7日 |
1.0 | 2005年12月13日 |
Railsプロジェクト作成
簡易な作成方法
簡易な方法を記載する。
筆者の動作環境を以下に示す。
|
|
|
|
作業ディレクトリとして ${TMPDIR}rails-playground
を作成する。
|
|
${TMPDIR}rails-playground
に Gemfile
を作成する。
|
|
Bundler
をインストールして、 bundle install
を実行する。
|
|
以下に実行結果を示す。
|
|
Railsアプリケーションプロジェクトを作成する。
|
|
以下に実行結果を示す。
|
|
アプリケーションを立ち上げて http://localhost:3000 にアクセスする。
|
|
DevContainerを用いる方法
作業ディレクトリとして ${TMPDIR}rails-playground/rails-devcontainer-sample
を作成する。
|
|
.devcontainer
を作成する。
|
|
.devcontainer
に devcontainer.json
を作成する。
|
|
Gemfile
を ${TMPDIR}rails-playground/rails-devcontainer-sample
に作成する。
|
|
Visual Studio Code (以下、VSCode)で開く。
code .
VS Codeでリモートコンテナーを開くと devcontainer.json
の updateContentCommand
に従って bundle install
が実行される。
rm Gemfile Gemfile.lock rails new . --minimal
アプリケーションを立ち上げて http://localhost:3000 にアクセスする。
rails server
番外編 - Bundlerでインストール先をvendor/bundleに指定する
BundlerでGemパッケージをインストールする際にインストール先を指定できるオプションがあるが、このオプションを使うとBundler v2.5.6 では以下の通り --path
ではなく bundle config set path vendor/bundle
を使うことを推奨する。
$ bundle install --path vendor/bundle [DEPRECATED] The `--path` flag is deprecated because it relies on being remembered across bundler invocations, which bundler will no longer do in future versions. Instead please use `bundle config set path 'vendor/bundle'`, and stop using this flag <中略>
以下は bundle install --path vendor/bundle
を使うケースである。この方法は作業ディレクトリを設けて、そこにRailsプロジェクト作成専用のRailsをインストールする。
作業ディレクトリに移動する。
|
|
Gemfileを作成する。
|
|
Railsインストール用のステップとしてBundlerコマンドを実行する。
|
|
Railsプロジェクトを作成する。
|
|
後処理としてRailsインストール用のステップでインストールしたRailsを削除する。
|
|
データベース接続
rails new
でデータベースを指定しなかった場合、SQLite 3を使う。
MySQL
RailsでMySQLに接続する場合はGemパッケージ mysql2
を使う。
- RubyGems https://rubygems.org/gems/mysql2
- GitHub https://github.com/brianmario/mysql2
Gemfileに以下の記述を加える。(執筆時では0.5.6が最新)
|
|
macOSでの諸注意
macOS (Sonoma 14.4) でGemパッケージ mysql2
をインストールする場合は、以下のコマンド実行が必要な可能性がある。
|
|
scaffold
rails generate scaffold
を実行すると、コントローラー、モデル、ビュー、ルーティング、テストコードを作成する。
ye#+begin_src :eval no rails generate scaffold User name:string rails db:migrate
#+end_src
なお、 db:migrate
を実行していない場合は ActiveRecord::PendingMigrationError
が発生する。
ルーティング
ルーティングについて『Ruby on Rails 7 ポケットリファレンス』のP368に記載がある。以下に引用する。
ルーティングとは、リクエストURLに応じて処理の受け渡し先を決定すること、またはそのしくみのことをいいます。Railsでは、クライアントからの要求を受け取ると、まずはルーティングを利用して呼び出すべきアクションを決定します。
ルーティング設定の基礎
ルーティング設定は config/routes.rb
に記述する。以下に例を示す。
|
|
ルーティングはコマンド bin/rails routes
で確認できる。以下に例を示す。
|
|
パラメーター制約
例えば、以下のように article
が受付可能なパラメーターを定義できる。
|
|
以下はコマンド bin/rails routes
の実行結果である。articles#showなどでidに指定できる値に制限が加わっていることがわかる。
|
|
アクション定義の幅
リソースを指定した場合、index, create, new, edit, show, update, destroyを自動で定義する。時によって、この定義は過剰な場合がある。
その場合はexceptもしくはonlyを使用する。以下はリソースarticlesに対してdestroyを除外するためにexceptを使用する例である。
|
|
以下はコマンド bin/rails routes
の実行結果である。destroyが存在しない。
|
|
コントローラーの指定
ルーティング設定でリソース名だけ指定した場合、自動で対応するコントローラーが決まる。以下の例ようのようにコントローラーの指定も可能である。
|
|
以下はコマンド bin/rails routes
の実行結果である。コントローラーがarticlesではなくgoodsになっていることがわかる。
|
|
トップページの定義
トップページを config/routes.rb
に定義できる。以下に例を示す。
|
|
なお、Railsはルート定義よりも public/index.html
を優先する点に留意すること。
TODO getとは?
TBD.
TODO リダイレクト
TBD.
コントローラー
MVCにおけるControllerについて取り扱う。
コントローラー作成
rails generate
コマンドでコントローラーを作成する。同コマンドの詳細は rails generate controller --help
で確認できる。以下にはコントローラー作成の一例を示す。
|
|
上述のコマンドは以下を作成する。
- app/controllers/products_controller.rb
- app/views/products … フォルダ
- app/helpers/products_helper.rb
- test/controllers/products_controller_test.rb
なお、コントローラー作成時にアクション(index, showなど)を指定できる。以下に例を示す。
|
|
前述のコマンドは以下のファイル、フォルダを作成する。
- app/controllers/photos_controller.rb
- app/views/photos
- app/views/photos/index.html.erb
- app/views/photos/create.html.erb
- app/views/photos/new.html.erb
- app/views/photos/edit.html.erb
- app/views/photos/show.html.erb
- app/views/photos/update.html.erb
- app/views/photos/destroy.html.erb
- test/controllers/photos_controller_test.rb
- app/helpers/photos_helper.rb
また、アクションを指定した場合にはルーティング設定 (config/routes.rb) に変更が入る。
|
|
モジュール名指定
|
|
実行結果例
rails generate controller admin::home index create app/controllers/admin/home_controller.rb route namespace :admin do get 'home/index' end invoke erb create app/views/admin/home create app/views/admin/home/index.html.erb invoke test_unit create test/controllers/admin/home_controller_test.rb invoke helper create app/helpers/admin/home_helper.rb invoke test_unit
この書き方も同様の結果となる。
|
|
実行結果例
rails generate controller admin/home index create app/controllers/admin/home_controller.rb route namespace :admin do get 'home/index' end invoke erb create app/views/admin/home create app/views/admin/home/index.html.erb invoke test_unit create test/controllers/admin/home_controller_test.rb invoke helper create app/helpers/admin/home_helper.rb invoke test_unit
アクション定義
アクションはコントローラーに記述する。アクションはパブリックメソッドであること。
|
|
リクエストヘッダ
リクエストヘッダの情報は request.headers
から取得できる。
|
|
|
|
HTTPステータスコード
RailsにはHTTPステータスコードに応じたシンボル定義がある。
https://railsguides.jp/layouts_and_rendering.html に詳細な表がある。
ステータスコード | 用途 | シンボル |
200 | 正常応答 | :ok |
400 | 不正なリクエスト | :bad_request |
401 | 未認可 or 未承認 | :unauthorized |
403 | アクセス禁止 | :forbidden |
404 | リソースがない | :not_found |
500 | サーバーの内部エラー | :internal_server_error |
503 | サービス利用不可 | :service_unavailable |
renderメソッドはHTTPステータスコードを示す :status
を持つ。以下に例を示す。
|
|
ビューテンプレートを指定する
Railsはコントローラーとアクションの名称からレスポンスで使うビューテンプレートを選ぶためアプリ開発者は何もしないで済む。ただ、異なるアクションを指定したり、そもそもコントローラーも別のものを指定したい場合がある。
別のアクションを指定したい場合は以下のようにする。
|
|
別のコントローラーを指定したい場合はアクションも併せて指定する。 template:
を使う。以下に例を示す。
|
|
プレーンテキストのレスポンス
|
|
JSONレスポンス
|
|
render json:
でJSON形式の応答をする。以下のJSONは整形したもの。
|
|
XMLレスポンス
XML応答をしたい場合はGemパッケージactivemodel-serializers-xmlを使う。GitHubにコードがある。
|
|
render xml:
でXML形式の応答をする。
|
|
以下はXML応答の結果である。
|
|
なお、Gemパッケージactivemodel-serializers-xmlがない状態では以下のようなXML応答になる。
TBD: XML例
TODO バイナリレスポンス
TBD.
- send_file
- send_data
応答可能な拡張子の定義
config/initializers/mime_types.rb
に記述する。例えばUSDZファイルを返したい場合は次のようにする。
|
|
コントローラーのアクションに respond_to
で処理を分岐する。
|
|
ウェブブラウザでアクセスした際のURL(拡張子)で処理が分岐する。
なお、USDZ形式のファイルは https://developer.apple.com/augmented-reality/quick-look/ で3D modelsのところから入手できる。
ログ出力
Railsのコントローラーで以下のログレベルでログ出力ができる。
- unknown(log)
- 不明なエラー
- fatal(log)
- 致命的なエラー
- error(log)
- エラー
- warn(log)
- 警告
- info(log)
- 情報
- debug(log)
- デバッグ用情報
|
|
ログはRailsプロジェクトフォルダ直下のlogフォルダに保存する。
ログ削除
蓄積したログは以下のコマンドで削除する。
|
|
TODO セッション
TBD.
TODO クッキー
TBD.
TODO ビュー
MVCにおけるViewについて取り扱う。
テンプレート変数 (名称要確認)
コントローラーのアクションメソッドからビューテンプレートに変数を介してデータを渡せる。
app/controllers/articles_controller.rb
|
|
app/views/articles/index.html.erb
|
|
出力結果のHTML
|
|
ハイパーリンク
|
|
|
|
TODO レイアウト
TBD.
TODO 部分テンプレート
部分テンプレートはファイル名をアンダースコア _
から始める。ファイルの格納先はRuby on Rails 7 ポケットリファレンスによると以下の通りである。
-
特定のコントローラーの場合
- app/views/{controller_name}
-
アプリケーション全体で共有する場合
- app/views/application
- app/views/shared
以下は例である。
app/controllers/articles_controller.rb
|
|
app/views/articles/index.html.erb
|
|
app/views/articles/_article_list.html.erb
|
|
出力結果のHTML
|
|
モデル
RailsはORMフレームワークActive Recordを提供する。本節はActive Recordの利用を前提におく。
モデルを定義する
rails generate model
コマンドはモデルを自動生成する。
例えば、nameとemailを持つUserモデルを作成する場合は以下のコマンドを実行する。
|
|
nameの後ろにフィールドの型を指定している。 rails generate model --help
の『Available field types:』では指定できる型として以下を挙げている。
- integer
- primary_key
- decimal
- float
- boolean
- binary
- string
- text
- date
- time
- datetime
このコマンドを実行すると、Userクラスが定義される。 app/models/user.rb
で確認できるだろう。
またマイグレーションと呼ばれる新しいファイルが生成される。
|
|
|
|
|
|
rails console
コマンドで対話形式の画面に切り替わる。その画面でテーブル定義を確認できる。
|
|
以下のようにテーブル一覧やカラム一覧を確認する。
|
|
TODO モデルに依存関係を付与する
モデル作成・取得・削除
rails console
でUserモデルを例にした操作になるが、アプリケーションのコードでも同じように User.all
といったように使える。
create
レコード登録
|
|
all
|
|
find
|
|
find_by
|
|
where
|
|
update
|
|
destroy
|
|
Active Support
blank?
blank?
メソッドは真偽値を返す。
false, nil, 空配列、空のハッシュ、空文字列の場合に true
を返す。それ以外に false
を返す。
true.blank? # => false false.blank? # => true nil.blank? # => true [].blank? # => true {}.blank? # => true "".blank? # => true " ".blank? # => true
present?
present?
メソッドは真偽値を返す。
true.present? # => true false.present? # => false nil.present? # => false [].present? # => false {}.present? # => false "".present? # => false " ".present? # => false
try
2.5 try - Active Support コア拡張機能 - Railsガイド
def foo user = User.new('Tanaka') user.info = nil if user.info.try(:name) puts 'Hello Tanaka' else puts 'Hello World' end end foo # => 'Hello World'
Active Record
カラム定義
カラム追加
カラムを追加するにはadd_columnメソッドを使う。
以下はusersテーブルにemailカラムを追加する例である。
|
|
NOT NULL制約
カラムにNOT NULL制約を付与する方法はカラム追加時、既存のカラムで異なる。
カラム追加時はadd_columnメソッドの null
オプションを使う。以下に例を示す。
|
|
既存のカラムに対してはchange_column_nullメソッドを使う。第3引数でNOT NULL制約を付与できる。以下に例を示す。
|
|
NOT NULL制約を外したい場合はchange_column_nullメソッドの第3引数をtrueにする。
UNIQUE制約
カラムにUNIQUE制約を付与するにはadd_indexメソッドの unique
オプションを使う。
以下はusersテーブルのemailカラムにUNIQUE制約を付与する例である。
|
|
カラムにUNIQUE制約を付与すると併せてインデックスも付く。
UNIQUE制約を外したい場合は remove_index
メソッドでインデックスを外す。
FOREIGN KEY制約
カラムにFOREIGN KEY制約を付与するにはadd_foreign_keyメソッドを使う。
以下はarticlesテーブルにFOREIGN KEY制約を付与するためにusersテーブルを指定した例である。この場合、 articles.user_id
と users.id
が結び付く。
|
|
カラムからFOREIGN KEY制約を外すにはremove_foreign_keyメソッドを使う。
以下はarticlesテーブルからFOREIGN KEY制約を外す例である。
|
|
インデックス
カラムにインデックスを付与するにはadd_indexメソッドを使う。
以下はusersテーブルのemailカラムにインデックスを付与する例である。
|
|
カラムからインデックスを外すにはremove_indexメソッドを使う。
以下はusersテーブルのemailカラムからインデックスを外す例である。
|
|
デフォルト値
カラムのデフォルト値はカラム追加時にadd_columnメソッドの default
オプションで指定するかchange_column_defaultメソッドを使う。
例えば、usersテーブルのstatusカラムのデフォルト値が draft だったものを NULL にしたい場合は以下となる。
|
|
from
オプションと to
オプションを使いマイグレーションに可逆性を持たせることができる。
CSSバンドル
Rails 7のリリースノートでcssbundling-railsを導入したことに触れている。Ruby on Rails GuidesのThe Asset Pipeline 10.3 cssbundling-railsでは以下のように紹介している。
cssbundling-rails allows bundling and processing of your CSS using Tailwind CSS, Bootstrap, Bulma, PostCSS, or Dart Sass, then delivers the CSS via the asset pipeline.
Sass - dartsass-rails
SassのコンパイラにDart Sassがある。このDart SassをRailsでも利用できるようにしたGemパッケージがdartsass-railsである。
インストール方法
dartsass-railsの導入方法はRuby on Rails Guidesの10.4 dartsass-railsにGitHubのrails/dartsass-railsを参照するようにと記載がある。そのGitHubのページはインストール方法として以下のコマンドを示している。
|
|
同パッケージのインストーラーは app/assets/stylesheets/application.scss
を作成する。このファイルはインストール直後からSassコンパイラの対象である。コンパイル処理はコマンド ./bin/dev
で実行する。このコマンドはRailsプロジェクトフォルダ直下にある Procfile.dev
(以下に例)に依存する。
|
|
dartsass-railsはコンパイル結果を app/assets/builds/
に出力する。
設定ファイル
app/assets/stylesheets/application.scss
以外のSassを設ける場合、 config/initializers/dartsass.rb
を作成して設定する。
|
|
TODO RSpec
TBD.
Swagger
Ruby on RailsでSwaggerを使う場合、以下のGemパッケージが候補に出ると思われる。
-
rswag
-
committee-rails
rswag
インストール方法
インストール方法はREADMEのGetting Startedに記載があるが、補足の手順が必要だったため、以下に記録を残す。
Gemfile
に以下を記述する。
|
|
Gemパッケージをインストールする。
|
|
rails
コマンドを実行する。
|
|
サンプルとして spec/requests/blogs_spec.rb
を作成する。READMEのGetting Startedの3にあるソースコードを作成した blogs_spec.rb
にコピー&ペーストする。
rails rswag
を実行して swagger.yml
を生成する。同コマンドは app/swagger/v1/swagger.yaml
を作成する。
なお、 rails rswag
は rails rswag:specs:swaggerize
のエイリアスである。
|
|
http://127.0.0.1:3000/api-docs にアクセスする。
注: 筆者の場合、 rails server -p 3001
としている。
file:./images/rails/rswag_01.png
TODO API定義の仕方
TBD.
Lint
使い方
以下のコマンドでLintを実行できる
rubocop
Bundlerでrubocopをインストールした場合、以下のコマンドでも実行可能
bundle exec rubocop