Active Record

## Active Recordの役割
**Active Record**とは、モデルの重要な役割を担うRailsコンポーネントの一つ。具体的には、データベースのテーブルとモデルの関係付けを行う役割を担っている。一般的にそのような役割を果たす仕組みを**ORM**(Object-Relational Mapping)と呼ぶ。

基本的にデータベース操作ではSQLを使用する。データベースの種類の違いを引き受け、ORMが共通語のような形でメソッドを利用できるようにしている。

## モデルの作成手順

* 対象となるモデルの作成

```ruby
$ rails g model User name:string email:string
```
<br>

* マイグレーションを実行し、モデルに対応するテーブルを作成

**マイグレーション**とは、マイグレーションファイルを使ってRails側から別の世界にあるデータベースを作成・更新するための作業。モデル生成時に作成されたファイル情報をもとにマイグレーションを行う。
```ruby
$　rails db:migrate
```

マイグレーションを実行することで、最新のデータベーステーブル構造などの情報を反映した**スキーマ**が作成される。
<br>
* シード機能の利用
シードを利用することで、あらかじめテーブルに入れておきたい固有情報を登録することができる。
seeds.rbファイルに記述すれば、データを登録することができる。

## CRUD操作
##### Create:新規作成
```ruby
$ User.create（name: "田中", email: "sample@aaa.com"）
```
モデルクラスのメソッドを直接呼び出して利用可能な、newとsaveを一連で行うメソッド。createメソッドでは、バリデージョンにエラーが発生しても、falseとして評価することができないため、基本的はsaveを利用する。
```ruby
$ @user1 = User.new（name: "田中", email: "sample@aaa.com"）
$ @user1.save
```


##### Read:読み出し
* find(id値)
```ruby
$ User.find（id）
```
指定されたidを持つデータを取得し、対応するモデルのインスタンスを生成する。

* find_by(条件)
```ruby
$ User.find_by（name:"山田"）
```
指定された条件に一致するデータを取得し、対応するモデルのインスタンスを生成する。

##### Update:更新
* update
モデルのクラスに対して更新するクラスメソッド
```ruby
$ User.update（id, {name:"鈴木"}）
```

モデルのインスタンスに対して更新するインスタンスメソッド
```ruby
$ user1 = User.find(id)
$ user1.update（name:"山田"）
```

##### Delete:削除
* destory
モデルのクラスに対して更新するクラスメソッド
```ruby
$ User.destroy（id）
```

モデルのインスタンスに対して更新するインスタンスメソッド
```ruby
$ User.find（id）.destroy
```

## バリデーション
**バリデーション**とは、入力されたデータか妥当かどうかを評価し、適正なデータだけをデータベースに取り込むための機能。
実装方法は大きく分けると、標準のヘルパーを利用する方法と、独自のヘルパーを利用する二つの方法がある。
また、独自のヘルパーを作成するには、モデル内でメソッドを設定する方法とValidatorクラスを使用して作成する方法がある。

### バリデーションの使用例
Userモデルに次のように書くと
```ruby
class User < ApplicationRecord
  validates :name, presence:true, length: {maximum: 100}
```
nameが入力されていない場合はエラーとなり、長さは最大100文字までとなる。

### 正規表現について
入力された値や文字列が、決められたパターンに該当しているかどうかを評価するとき**正規表現**を使用する。「/・・・/」のように/で囲むことで正規表現を表す。
```
/\A\d{3}-\d{4}\z/
```
郵便番号などはこのように表現される。

## アソシエーション
データリソースを管理するデータベースを対して、データの整合性を確保することを**正規化**といいます。Railsにおいて、正規化を用いてモデル間の関係を定義する仕組みが**アソシエーション**です。

#### has_many
自身が他のモデルに対して一対多の関係を持つことを定義する。
```ruby
# ユーザーモデルから各ユーザーを見た時の関係
class User < ApplicationRecord
  has_many :users
end
```

#### has_one
自身が他のモデルに対して一対一の関係を持つことを定義する。
```ruby
# ユーザーモデルから電話番号を見た時の関係
class User < ApplicationRecord
  has_one :phone_number　
end
```

#### belongs_to
他のモデルとの一対多の関係を持つことを定義する。
```ruby
# 投稿モデルからユーザーを見た時の関係
class Post < ApplicationRecord
  belongs_to :users　
end
```

### 外部キーの設定方法
Railsの標準ルールでは、子モデルに属性タイプをreferencesとし、親モデル名を属性にすれば、親モデルIDを子モデルの属性とすることができる。例えば、親モデル「Teacher」、子モデル「Students」があるとき
```ruby
$ rails g model teacher name:string
$ rails g model students name:string teacher:references
```
とすれば、「teacher_id」がStudentsモデルの外部キーとなる。

### 単一テーブル継承(STI)
データベースの1つのテーブルに対応するモデルをもとにして、複数の異なるモデルに継承させる**単一テーブル継承**(Single Table Inheritance)という関係がある。

ペットを管理するPetモデルと、それを継承するDogモデルとCatモデルを生成する。データベースのテーブルはPetモデルだけに紐づいていて、DogとCat、それぞれのデータはPetsテーブルの中で管理される。

まずPetモデルを次のように生成する。typeカラムを持たせることで、継承されるモデルのクラス名が保存される。

```ruby
$ railg g model pet type:string name:strig
```

Petモデルが次のように生成される。

```ruby:pet.rb
class Pet < ApplicationRecord
end
```
継承するDogモデルとCatモデルは次のようにエディタで作成する。
```ruby:dog.rb
class Dog < Pet
end
```
```ruby:cat.rb
class Cat < Pet
end
```
これでDog,Catモデルそれぞれのインスタンスを作成し、利用することができるようになる。