ぺーぺーSEのブログ

備忘録・メモ用サイト。

Ruby on Rails入門

サンプルアプリを作りながらRuby on Railsの全体像を把握する。
実行環境構築は以下を参照。

blog.pepese.com

また、ここでの実行環境は以下。

> ruby -v
ruby 2.3.1p112 (2016-04-26 revision 54768) [x64-mingw32]

> rails -v
Rails 5.0.0.1

Ruby on Railsアプリケーションの作成

Ruby on Railsではrailsコマンドを使って設定ファイルやソースを半自動生成しながら開発する。
アプリケーションの作成には「rails new」コマンドを使用する。

rails newコマンド

rails new [アプリ名] [options]

rails newコマンドのオプション(rails new --helpで詳細出る)

オプション 説明 デフォルト
-r, -ruby=PATH ruby実行ファイルまでのパス
-m, -template=TAMPLATE アプリケーションテンプレートのパス
-d, --database=DATABASE データベースの種類 sqlite3
-j, --javascript=JAVASCRIPT 組み込むJavaScriptライブラリーを指定。 jquery
--skip-gemfile Grmfileを作成しない 作成する
ーB, --skip-bundle bundle installを行わない installする
-G, --skip-git .gitignoreを作成しない 作成する
--skip-keeps .keepを作成しない 作成する
-M, --skip-action-mailer Active Mailerを作成しない 作成する
-O, --skip-active-recode Active Recordを作成しない 作成する
-P, --skip-puma Pumaを関連付けない する
-C, --skip-action-cable Action Cableを作成しない 作成する
-S, --skip-sprockets Sprocketsを作成しない 作成する
--skip-spring springアプリケーションをインストールしない
--skip-listen listen gemに依存した設定を作成しない
-J, --skip-javascript javascriptを組み込まない
--skip-turbolinks turbolinks gemをスキップする
-T, --skip-test-unit test::unitを組み込まない
--dev github リポジトリ上の自分のコードから作成
--edge github リポジトリ上の最新のコードから作成
--rc=RC Railsコマンドのオプションファイルを指定
--no-rc .railsrcファイルをロードしない する
--api APIのみのアプリケーション設定
-f, --force ファイルが存在する場合に上書きする
-p, --pretend ドライランする しない
-q, --quiet 進捗情報を表示しない する
-s, --skip 既に存在するファイルについてはスキップ しない
-h, --help ヘルプ
-v, --version バージョンを表示

1.「C:\workspace\rails」を作成してcdする。
2.「rails new sample」をうつ。
sampleというアプリケーションのスケルトンが作成される。
バージョンを指定したい場合は「rails _4.2.7_ new sample」のように打つ。
ディレクトリツールはこんな感じ。(一部省略)

> tree /f .
C:.
│  config.ru       # Rack設定ファイル(Ruby製Webサーバ)
│  Gemfile         # Gemの定義ファイル
│  Rakefile        # Rakeの定義ファイル
├─app              # アプリのクラス、設定ファイル
│  ├─assets        # アセット(image/js/css)
│  ├─channels      #  WebSocketクラス
│  ├─controllers   # コントローラクラス
│  ├─helpers       # ビューヘルパー
│  ├─jobs          # Active Jobクラス
│  ├─mailers       # Active Mailerクラス
│  ├─models        # モデルクラス
│  └─views         # ビュー(ERBなど)
├─bin              # 各種スクリプトを配置
├─config           # 各種設定ファイルを配置
│  ├─environments  # 環境別設定ファイル
│  ├─initializers  # 初期化用設定ファイル
│  └─locales       # 国際化用設定ファイル
├─db               # データベース定義、設定ファイル
├─lib              # 自作ライブラリ置き場
├─log              # ログ出力先
├─public           # 公開ファイル置き場
├─test             # テストスクリプト
├─tmp              # テンポラリ
└─vendor           # サードパーティJS/CSS置き場

3.「rails server」をうつ。
WEBrickというRails組み込みのHTTPサーバが起動する。
4.ブラウザで「http://localhost:3000」へアクセス。
「Yay! You’re on Rails!」って出る! HTTPサーバを停止するときはDOSでCtr+cでとまる。

Rails開発の基本

Railsは大枠はMVC単位で開発していく。
MVC以外にも作成単位があり、いずれも「rails generate」コマンドを使用してソースコードを半自動生成して開発を進めていく。
ここでは、上記のサンプルアプリをもとにMVCを作成していく。

rails generateコマンド

rails generate GENERATOR [args] [options]

GENERATORには以下の種類がある。(rails generate --help)

Rails:
  assets
  channel
  controller
  generator
  helper
  integration_test
  jbuilder
  job
  mailer
  migration
  model
  resource
  scaffold
  scaffold_controller
  task

Coffee:
  coffee:assets

Js:
  js:assets

TestUnit:
  test_unit:generator
  test_unit:plugin

GENERATORの種類によって以下のファイルが生成される。(オプションで多少変化する)

GENERATOR コントローラ ビュー モデル マイグレーション アセット ルーティング テスト ヘルパー
assets × × × × × × ×
controller × ×
generator × × × × × × × ×
helper × × × × × ×
integration_test × × × × × × ×
jbuilder × × × × × × ×
mailer × × × × × × ×
migration × × × × × ×
model × × × × ×
resource
scaffold
scaffold_controller × × × ×
task × × × × × × × ×

ちなみに失敗したら「rails destroy GENERATOR」コマンドで削除できる。

コントローラ(C)の作成

■rails generate controllerコマンド

rails generate controller [NAME] [action action] [options]
  • NAME
    • コントローラ名
    • [NameSpace]/コントローラ名」とスラッシュで区切ると名前空間を設定できる。
      • 名前空間を設定するとディレクトリが分割されたり、名前空間名のプレフィックスがついたりする
  • action
    • アクション名を指定
    • 作成されるコントローラクラスのメソッド(アクションメソッド)となる

■rails generate controllerコマンドのオプション

  • 「--skip-namespace」/「--no-skip-namespace」
    • 名前空間設定がスキップされる(デフォルト:スキップしない)
  • 「-e [NAME]」「--template-engine=[NAME]」
    • 使用するテンプレートを指定(デフォルト:erb)
  • 「-t [NAME]」「--test-framework=[NAME]」
    • 使用するテスティングフレームワークを指定(デフォルト:test_unit)
  • 「--helper」
    • ヘルパーを作成するか(デフォルト:true)
  • 「--assets」
    • アセットを作成するか(デフォルト:true)

1.「C:\rubyWorkspace\sample」へcd
2.「rails generate controller hello index」をたたく
ディレクトリツリーはこんな感じ。(新規作成された箇所のみ)

create  app/controllers/hello_controller.rb
 route  get 'hello/index'
invoke  erb
create    app/views/hello
create    app/views/hello/index.html.erb
invoke  test_unit
create    test/controllers/hello_controller_test.rb
invoke  helper
create    app/helpers/hello_helper.rb
invoke    test_unit
invoke  assets
invoke    coffee
create      app/assets/javascripts/hello.coffee
invoke    scss
create      app/assets/stylesheets/hello.scss

3.コントローラクラス(hello_controller.rb)を編集

class HelloController < ApplicationController
  def index
    render text: 'Hello World !' # この行を追加!
  end
end

4.ルーティングの設定(/config/routes.rb)
アクセスURIとコントローラクラス+アクションメソッドとの紐付を「routes.rb」で行う。
今回はrails generateコマンドで自動生成されている部分の確認。

Rails.application.routes.draw do
  get 'hello/index' # この行が自動で追加されている
end

HTTPメソッドGetで「http://localhost:3000/hello/index」へアクセスするとhelloクラスのindexメソッドが呼び出される。
また、「rake routes」コマンドで現在有効なルートをリスト表示してくれる。

5.「rails server」をたたく
とめていなければ実行する必要はない。

6.ブラウザで「http://localhost:3000/hello/index」へアクセス
「Hello World !」と表示される。
これはhelloコントローラクラスのindexアクションで「render text: 'Hello World !'」の出力がそのまま表示されているだけで、ビュー機能は使用していない。

ビュー(V)の作成

Viewはrails generateコマンドで既に作成されており、「app/views/hello/index.html.erb」にある。
rails generateコマンドを実行する際、actionを指定しておくとアクションメソッドと同じファイル名(+.html.erb)で作成される。
ERB(拡張子erb)はEmbedded Rubyの略でRubyで使用されるテンプレートエンジン。

1.コントローラクラス(hello_controller.rb)を編集

class HelloController < ApplicationController
  def index
    # render text: 'Hello World !' # コメントアウト
    @msg = 'Hello World !'         # 追加行
  end
end

アットマーク(@)を付けた変数はテンプレート変数といい、ビューへ値を引き渡す役目になる。

2.ビュー(views/hello/index.html.erb)を編集

<h1>Hello#index</h1>
<p>Find me in app/views/hello/index.html.erb</p>
<%= @msg %> <!-- この行を追加-->

「@msg」はテンプレート変数でコントローラのアクションメソッドから値が渡される。

3.「rails server」をたたく
とめていなければ実行する必要はない。

4.ブラウザで「http://localhost:3000/hello/index」へアクセス
テンプレートで記述されている「Hello#index」「Find me in app/views/hello/index.html.erb」と テンプレート変数で引き渡した「Hello World !」が表示される。

ビュー(V)の変更

helloコントローラクラスのindexでテンプレート変数を使用すると「views/hello/index.html.erb」のERBテンプレートが自動的に選択される。 コントロールクラスで

render '[PATH]'

を記述するとテンプレートを指定することができる。
PATHは「/app/views」ディレクトリからの相対パスで記載し、.html.erbは省略する。

1.ビュー用のテンプレートファイル(views/hello/sampleView.html.erb)を作成

<h1>Sample View Page</h1>
<%= @msg %>

★ERBテンプレートは文字コードをUTF-8で保存する。

2.コントローラクラス(hello_controller.rb)を編集

class HelloController < ApplicationController
  def index
    # render text: 'Hello World !'
    @msg = 'Hello World !'
    render 'hello/sampleView' # この行を追加
  end
end

3.「rails server」をたたく
とめていなければ実行する必要はない。

4.ブラウザで「http://localhost:3000/hello/index」へアクセス
ブラウザで表示されたページのソースを見ると「Sample View Page」と表示されて、先ほど自作したテンプレートが使用されていることがわかる。
表示されたページをソースで見ると、なにやらその他にたくさんhtmlタグが追加されている。
これはレイアウトテンプレートというものが使用されている。
app/views/layouts/application.html.erb」を見ると「<%= yield %>」という部分があり、ここに作成したテンプレートが適用されるようになっている。
されにstylesheetやjavascriptはコントローラ単位でディレクトリがわけられて作成されたものが自動反映されるようになっている。
レイアウトの自動反映がイヤな場合は「application.html.erb」を削除もしくはリネームする。

モデル(M)の作成

Rails標準のO/RマッパーであるActive Recoredが使用できる。

■rails generate modelコマンド

rails generate model NAME [field[:type][:index] field[:type][:index]] [options]
  • NAEM
    • モデル名
    • [NameSpace]/モデル名」とスラッシュで区切ると名前空間を設定できる。
      • 名前空間を設定するとディレクトリが分割されたり、名前空間名のプレフィックスがついたりする
  • field[:type][:index]
    • フィールド名、データ型、インデックスを指定
    • type(データ型)には以下が指定できる
      • integer
      • primary_key
      • decimal
      • float
      • boolean
      • binary
      • string
      • text
      • date
      • time
      • datetime
      • timestamp
    • index(インデックス)には以下が指定できる
      • unique
      • index

■rails generate modelコマンドのオプション

  • 「--skip-namespace」/「--no-skip-namespace」
    • 名前空間設定がスキップされる(デフォルト:スキップしない)
  • 「-o [NAME]」「--orm=[NAME]」
    • 使用するO/Rマッパーを指定(デフォルト:active_record)

■Active Recordのオプション

  • 「--migration」/「--no-migration」
    • マイグレーションファイルを作成するか否か(デフォ:する)
  • 「--timestamps」/「--no-timestamps」
    • タイムスタンプ列(created_at、updated_at)を作成するか否か(デフォ:する)
  • 「--parent=[PARENT]」
    • モデルの親クラスを指定
  • 「--indexes」/「--no-indexes」
    • 外部キーにインデックスを付与するか否か(デフォ:する)
  • 「-t [NAME]」「--test-framework=[NAME]」
    • 使用するテスティングフレームワークを指定(デフォ:test_unit)

■TestUnitのオプション

  • 「--fixture」/「--no-fixture」
    • フィクスチャを生成するか否か(デフォ:する)
  • 「-r [NAME]」「--fixture-replacement=[NAME]」
    • フィクスチァを変更する

1.「C:\rubyWorkspace\sample」へcd
2.「rails generate model user no:string name:string age:integer birthday:date active:boolean」をたたく
以下のようにファイルが更新される。

invoke  active_record
create    db/migrate/20161103065150_create_users.rb
create    app/models/user.rb
invoke    test_unit
create      test/models/user_test.rb
create      test/fixtures/users.yml

3.「rake db:migrate」をたたく
Railsにはマイグレーションというテーブルの作成・変更を行う機能がある。
マイグレーションを実行するためのファイルは「db/migrate/20161103065150_create_users.rb」に自動生成されている。

class CreateUsers < ActiveRecord::Migration[5.0]
  def change
    create_table :users do |t|
      t.string :no
      t.string :name
      t.integer :age
      t.date :birthday
      t.boolean :active

      t.timestamps
    end
  end
end

4.「rake db:fixtures:load FIXTURES=users」をたたく
Railsにはフィクスチャという機能があり、DBへテスト用データを下敷きする機能がある。
フィクスチャを実行するためのファイルは「test/fixtures/user.yml」に自動生成されている。

one:
  'no': MyString
  name: MyString
  age: 1
  birthday: 2016-11-03
  active: false

two:
  'no': MyString
  name: MyString
  age: 1
  birthday: 2016-11-03
  active: false

また、Railsでは「rails dbconsole」というコマンドでDBクライアントを起動することができる。

> rails dbconsole
SQLite version 3.15.0 2016-10-14 10:20:30
Enter ".help" for usage hints.
sqlite> .tables
ar_internal_metadata  schema_migrations     users
sqlite> .schema users
CREATE TABLE "users" (
  "id"         INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
  "no"         varchar,
  "name"       varchar, 
  "age"        integer, 
  "birthday"   date, 
  "active"     boolean, 
  "created_at" datetime NOT NULL, 
  "updated_at" datetime NOT NULL
);
sqlite> select * from users;
298486374|MyString|MyString|1|2016-11-03|f|2016-11-03 06:55:13.749144|2016-11-03 06:55:13.749144
980190962|MyString|MyString|1|2016-11-03|f|2016-11-03 06:55:13.749144|2016-11-03 06:55:13.749144
sqlite> .quit

※見やすくちょっとフォーマット変更している。

上記を確認するとわかるが、以下のフィールドが自動付与されている。 - id - 自動で連番になる主キー - created_at - レコードの作成日時 - updated_at - レコードの更新日時

5.コントローラクラス(hello_controller.rb)を編集
DBから全レコード取得するロジックを書く。

class HelloController < ApplicationController
  def index
    # render text: 'Hello World !'
    @msg = 'Hello World !'
    render 'hello/sampleView'
  end
  
  # 以下、追加メソッド
  def users
    @users = User.all
  end
end

6.ビュー用のテンプレートファイル(views/hello/users.html.erb)を手動で作成
コントローラで取得したデータをテーブルで表示する。

<table border='1'>
  <tr>
    <th>No</th>
    <th>名前</th>
    <th>年齢</th>
    <th>アクティブユーザ?</th>
  </tr>

<% @users.each do |user| %>
  <tr>
    <td><%= user.no %></td>
    <td><%= user.name %></td>
    <td><%= user.age %></td>
    <td><%= user.active %></td>
  <tr>
<% end %>

</table>

7.ルーティングの設定(/config/routes.rb)

Rails.application.routes.draw do
  get 'hello/index'
  get 'hello/users' # この行を追加
end

8.「rails server」をたたく
とめていなければ実行する必要はない。

9.ブラウザで「http://localhost:3000/hello/users」へアクセス

■補足 データベースの設定は「config/database.yml」にある。

用語メモ

  • gem
    • Rubyライブラリのパッケージ管理システム
      • Lunuxでいうaptやyumみたいなもの
  • bundler
    • gemを管理する仕組み
    • Gemfileでgemパッケージのバージョン指定などが行える
  • Rake
    • Rubyで記述された様々なタスクをコマンド実行できるツール
  • RVM(Ruby Version Manager)
    • 複数バージョンのRuby実行環境を共存させる仕組み

参考