Railsに入る前にしっておきたいERBとActiveRecordのこと

# Railsに入る前にしっておきたいERBとActiveRecordのこと

## これは何？

`Rails` をいきなり使うと覚えることが多くて大変！
ということで `Rails` をいきなりやる前に最低限の知識として

* ERB
* ActiveRecord

のことをちょっと紹介・説明をした記事となります

## ちょっとだけ用語説明

### ERBとは？

**Embedded RuBy** の略です。
これを使うことで、最終的に好きな **ファイルの中の任意の箇所でRubyのコードを実行する** ことができます。

## ActiveRecordとは

`Rails` に標準で入っている `Gem` です。
主にデータベース(以下 `DB`) との接続から値の取得を行なってくれる[ORM](https://qiita.com/yk-nakamura/items/acd071f16cda844579b9)です。

これを使うことで簡単に `DB` と `Ruby` の連携をすることができます

## ERB

### 使い方

基本的な使い方は非常に簡単です。
まず使いたい `Ruby` ファイルで `erb` のライブラリを読み込みます。

ここでは例として `erb_run.rb` というファイルを作ってみて以下のコードを書いてみましょう

```ruby:erb_run.rb
# erb の読み込み
require "erb"
```

これで使う準備が出来ました。
では実際に使ってみましょう。

まず以下のように文字列を渡してインスタンスを作成してください

```ruby:erb_run.rb
# erb の読み込み
require "erb"

erb = ERB.new("好きな文字列")
```

そして `.result` メソッドを実行して結果を受け取ってください。
この `.result` の戻り値が、文字列内の `Ruby` コードが実行された結果となります。
実際に表示をしてみてください


```ruby:erb_run.rb
# erb の読み込み
require "erb"

erb = ERB.new("好きな文字列")
puts erb.result
```

* 実行する

```bash
ruby erb_run.rb
#=> 好きな文字列
```

`好きな文字列` というのが表示されて入れば成功です！


### Rubyコードを書いて使ってみる

ただ同じ文字列が返ってきただけじゃん！
ということで今度は実際に `Ruby` のコードを実行してみましょう。

`ERB` は特定のルールに従った記載をすることで、`Ruby` のコードを記載することができます。
詳しくは [Googleで検索](https://www.google.com/search?q=ERB+%E8%A8%98%E6%B3%95&oq=ERB+%E8%A8%98%E6%B3%95)してみてください

下記のように `erb_run.rb` を変更して実行をしてみてください


```ruby:erb_run.rb
# erb の読み込み
require "erb"

erb = ERB.new('はじめての <%= "erb".upcase %>の実行')
puts erb.result
```

* 実行する

```bash
ruby erb_run.rb
#=> はじめてのERBの実行
```

`<%= %>` の中のRubyコードが実行されているのが確認できました。


このように文字列の中に存在する任意の `Ruby` コードを実行できるのが `ERB` の力です。
そして実際に `Rails` でもこの `ERB` が使われています。

### HTMLにRubyコードを仕込んでみる

もう少し実際に使用されているような使い方をしてみます。
以下のように `index.html` を作って `erb_run.rb` と同じ階層に配置してください

```erb:index.html
<html>
  <head>
  </head>
  <body>
    <h1>はじめてのERB</h1>
    <h2><%= "erb".upcase %>を実行する</h2>
    <% 1.upto(3) do |num| %>
      <p><%= num %></p>
    <% end %>
  </body>
</html>
```

では実際に上記の `html` の中に記載した `Ruby` コードを実行してみましょう。

`erb_run.rb` を以下のように変更して実行してください

```ruby:erb_run.rb
# erb の読み込み
require "erb"

# index.html の中身を文字列で取得する
index_html = File.read("index.html")

# ERB実行
erb = ERB.new(index_html)
puts erb.result
```

* 実行する

```bash
ruby erb_run.rb
#=>
<html>
  <head>
  </head>
  <body>
    <h1>はじめてのERB</h1>
    <h2>ERBを実行する</h2>
    
      <p>1</p>
    
      <p>2</p>
    
      <p>3</p>
    
  </body>
</html>
```

上記のように `html` の中の `Ruby` コードが実行されたのが確認できました。

### ERBまとめ

* `ERB` を使うと文字列に存在する `Ruby` コードを実行することができる
* そのときは `ERB` が用意した記法通りに `Ruby` コードを記載する必要がある
* `ERB` と `File.read` などの任意のファイルを文字列で読み込む処理を使うと `html` や `yml` などの外部ファイルの `Ruby` コードを実行することができる

#### Railsへの補足

実際に `Rails` では `app/views` の下に `ERB` で変換するファイルを配置します。
その際、それが `erb` で使用されることがわかるように拡張子の最後に `.erb` を付けています

* 例: `app/views/users/index.html.erb`

Rails では最終的にレンダリングされる `html` は `ERB` が実行した結果のものとなります

※ちなみに `config/database.yml` も `ERB` が実行された結果になるのですが、こいつは ~~何故か~~ `erb` が付いてないです

##### 追記

上記ですが @scivola さんより補足を頂きました。

`Rails` が拡張子で処理方法を判断する必要がないためではないか、ということです。コメントを読んで私もそうではないかと思いました。

詳しくは[コメント欄](https://qiita.com/toririn/items/dc34749268513fd75bf0#comment-bf13dbc3ab3720e77666)を参照ください

---

## ActiveRecord

### DBの環境構築

何はともあれ `DB` が必要です。
`Docker` でもなんでも良いので `DB` を用意してください。

#### Dockerで準備

ここでは一応 `Docker` の `MySQL` を使う前提でいきます。
以下のようにコマンドを実行して `mysql` に接続をしてください

```bash
# mysql イメージ取得
docker pull mysql
# コンテナ化
docker run --name mysql -e MYSQL_ROOT_PASSWORD=root -d -p 13306:3306 mysql
# 確認
docker ps
#=> CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                                NAMES
#=> XXXXXXXXXXXX        mysql               "docker-entrypoint.s…"   2 seconds ago       Up 1 second         33060/tcp, 0.0.0.0:13306->3306/tcp   mysql
# 接続
mysql -h 127.0.0.1 -u root -P 13306 -p
#=> Enter password: (rootと入力)
mysql>
```

#### データベースとテーブルとレコードを作成する

`SQL` を使って以下のデータベースとテーブルを作成しましょう

* データベース: `active_record_test`
* テーブル: `users`

```sql
mysql> CREATE DATABASE active_record_test;
#=>Query OK, 1 row affected (0.01 sec)
mysql> CREATE TABLE active_record_test.users (id INT, name VARCHAR(10), age INT, created_at DATETIME, updated_at DATETIME);
#=>Query OK, 0 rows affected (0.02 sec)
```

これで環境構築は完了です

### 使ってみる

#### Gemインストール

では `ActiveRecord` を使ってみましょう。
まず `ERB` と違い `ActiveRecord` は `Gem` ですので、インストール作業が必要です。以下のコマンドを実行して `activerecord` をインストールしてください

```bash
gem install activerecord
```

※最新の `activerecord` は `Ruby version >= 2.4.4` を要求してくるので古い `Ruby` を使っている型はインストールするバージョンを下げるか `Ruby` バージョンをあげててください

また今回は `MYSQL` を使うので `MYSQL` を使うための `Gem` もインストールが必要です。

```bash
gem install mysql2
```

※`mysql2` は `mysql` コマンドが使えないとインストールに失敗するのでホスト側で `mysql` を使うために必要なモジュール一式を入れておいてください

### ファイル作成1

ここでは例として `ar_run.rb` というファイルを作ってみて以下のコードを書いてみましょう
※`ar`は `ActiveRecord` の頭文字からとってきました

```ruby:ar_run.rb
# activerecord の読み込み
require "active_record"
# mysql2の読み込み
require "mysql2"
```

これで使う準備が出来ました。
では実際に使ってみましょう。

#### DBとの接続設定

まず以下のようにDBとの接続設定を記載します


```ruby:ar_run.rb
# activerecord の読み込み
require "active_record"
# mysql2の読み込み
require "mysql2"

# DB接続設定
ActiveRecord::Base.establish_connection(
  adapter:  "mysql2",
  database: "active_record_test",
  host: "127.0.0.1",
  port: "13306",
  username: "root",
  password: "root",
)
```

これで接続設定ができました

#### 実際に `users` テーブルを使ってみる

以下のように `ActiveRecord::Base` を継承したクラスを作成します。
そしてそのクラスで接続したいテーブル名を記載します。

```ruby:ar_run.rb
# activerecord の読み込み
require "active_record"
# mysql2の読み込み
require "mysql2"

# DB接続設定
ActiveRecord::Base.establish_connection(
  adapter:  "mysql2",
  database: "active_record_test",
  host: "127.0.0.1",
  port: "13306",
  username: "root",
  password: "root",
)

class User < ActiveRecord::Base
  self.table_name = "users"
end
```

これで下準備は完了です！

##### 保存処理

さっそくDBにレコードを保存してみましょう

idが `1`, 名前が `banana`, 年齢が `12` のレコードを作ってみます

```ruby:ar_run.rb
# activerecord の読み込み
require "active_record"
# mysql2の読み込み
require "mysql2"

# DB接続設定
ActiveRecord::Base.establish_connection(
  adapter:  "mysql2",
  database: "active_record_test",
  host: "127.0.0.1",
  port: "13306",
  username: "root",
  password: "root",
)

class User < ActiveRecord::Base
  self.table_name = "users"
end

puts User.create(id: 1, name: "banana", age: 12)
```

* 実行する

```bash
ruby ar_run.rb
#=> #<User:0x(ランダムな値)>
```

と表示されていたら作成成功です。実際にmysqlに接続してテーブル確認してみてください

```bash
mysql> SELECT * FROM active_record_test.users;
+------+--------+------+---------------------+---------------------+
| id   | name   | age  | created_at          | updated_at          |
+------+--------+------+---------------------+---------------------+
|    1 | banana |   12 | 201x-xx-xx xx:xx:xx | 201x-xx-xx xx:xx:xx |
+------+--------+------+---------------------+---------------------+
1 row in set (0.01 sec)
```

上記にように出力されていれば成功です！
※`created_at`, `updated_at` には `activerecord` が自動的に値を入れてくれています！

##### 取得する

今度は先ほど作ったレコードを取得してみます


```ruby:ar_run.rb
# activerecord の読み込み
require "active_record"
# mysql2の読み込み
require "mysql2"

# DB接続設定
ActiveRecord::Base.establish_connection(
  adapter:  "mysql2",
  database: "active_record_test",
  host: "127.0.0.1",
  port: "13306",
  username: "root",
  password: "root",
)

class User < ActiveRecord::Base
  self.table_name = "users"
end

# id が1のレコードを一件取得する
user = User.find_by(id: 1)

# テーブルのカラム名と同じメソッドを呼び出すと、取得したレコードの値を返してくれる
puts user.id
puts user.name
puts user.age
```

* 実行する

```bash
ruby ar_run.rb
#=> 1
#=> banana
#=> 12
```

上記のように出力されていれば成功です！

### ActiveRecordまとめ

* `ActiveRecord` を使うと `DB` に値を保存したり、値を取得したりすることが簡単にできる
* そのときは `ActiveRecord::Base` を継承したクラスを作成する
  * 取得など方法はたくさんあるので[Googleで検索](https://www.google.com/search?q=ActiveRecord+メソッド+一覧)してみてください

#### Railsへの補足

* `ActiveRecord` を使うために作成されるクラスが以下のときは `self.table_name` を省略できます
    * テーブル名の単数形のクラス名となっている
        * `User` クラスと `users` テーブル、など
* `Rails` では `ActiveRecord::Base.establish_connection` で使用する接続設定は `config/database.yml` に記載します
* `Rails` ではこうしたクラスは `app/models` に配置します
    * 例: `app/models/user.rb`

---

## 複合技

これらを複合して `users` テーブルのレコードの名前一覧を表示させるには以下のようにすればできます

```erb:users_index.html.erb
<html>
  <head>
  </head>
  <body>
    <h1>ユーザ一覧</h1>
    <% @users.each do |user| %>
      <p><%= user.name %></p>
    <% end %>
  </body>
</html>
```

```ruby:ar_erb_run.rb
# erb の読み込み
require "erb"
# activerecord の読み込み
require "active_record"
# mysql2の読み込み
require "mysql2"

# DB接続設定
ActiveRecord::Base.establish_connection(
  adapter:  "mysql2",
  database: "active_record_test",
  host: "127.0.0.1",
  port: "13306",
  username: "root",
  password: "root",
)

class User < ActiveRecord::Base
  self.table_name = "users"
end

# users テーブルのレコードを全て取得する
@users = User.all

# users_index.html.erb の中身を文字列で取得する
index_html = File.read("users_index.html.erb")

# ERB実行
erb = ERB.new(index_html)
puts erb.result
```

* 実行する

```bash
ruby ar_erb_run.rb 
#=>
<html>
  <head>
  </head>
  <body>
    <h1>ユーザ一覧</h1>
    
      <p>banana</p>
    
  </body>
</html>
```

## まとめ

* `Rails` を使う前に必要となる `ERB` と `ActiveRecord` の簡単な仕組みを説明しました
* `Rails` はこうした `Gem` やライブラリが複合的に使われてアプリケーションの作成がされています