テーブル設計(Active Hashを利用する)

# 概要
今回は、フリマアプリのクローンサイトを作る上でテーブル設計をしていきました。
初めて自作で作るのでテーブル設計のクオリティはまだまだですが、とりあえずアウトプットということで見逃してください、、、

## ER図
このようになりました。
![テーブル設計.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/696517/31a51428-7f87-6eaa-15b3-1ed426f07d13.png)

ポイントとしては、既存のデータから選択させるような箇所はActive Hashを用いてファイルを用意しておくことです。
商品のコンディションや、購入時の届け先の都道府県など、、、
都道府県を表すprefectures(active_hash)テーブルに関しては発送元と届け先で二箇所利用しています。

## Active Hashの使い方
### インストール
Gemfileに以下を記載してbundle installする。

```ruby:Gemfile
gem 'active_hash'
```

あとはActive Hash用のモデルを作成します。
⚠︎ターミナルでのコマンドで作らず、ActiveHash::Baseを継承したモデルを自作すること⚠︎

### ファイル記述

例として、カテゴリーのファイルをあげておきます。

```ruby:app/models/category.rb
class Category < ActiveHash::Base
  self.data = [
    {id: 1, name: '---'},{id: 2, name: 'レディース'},{id: 3, name: 'メンズ'},{id: 4, name: 'ベビー・キッズ'},{id: 5, name: 'インテリア・住まい・小物'},{id: 6, name: '本・音楽・ゲーム'},{id: 7, name: 'おもちゃ・ホビー・グッズ'},{id: 8, name: '家電・スマホ・カメラ'},{id: 9, name: 'スポーツ・レジャー'},{id: 10, name: 'ハンドメイド'},{id: 11, name: 'その他'}
  ]
end
```

### README

また、今回設計したテーブル、アソシエーションのREADMEは次のようになりました。

```README.md
# テーブル設計

## users テーブル
| Column      | Type   | Options     |
| ----------- | ------ | ----------- |
| nickname    | string | null: false |
| email       | string | null: false |
| password    | string | null: false |
| first_name  | string | null: false |
| family_name | string | null: false |
| read_first  | string | null: false |
| read_family | string | null: false |
| birth       | date   | null: false |

### Association

- has_many :products
- has_many :item_purchases
- has_many :comments

## products テーブル
| Column              | Type       | Options     |
| ------------------- | ---------- | ----------- |
| photo               | text       | null: false |
| name                | string     | null: false |
| explanation         | text       | null: false |
| category            | integer    | null: false |
| condition           | integer    | null: false |
| postage_type        | integer    | null: false |
| prefectures         | integer    | null: false |
| preparation_days    | integer    | null: false |
| value               | integar    | null: false |
| user                | references | null: false | 


### Association

- belongs_to :user
- has_one :item_purchase
- has_many :comments
- belongs_to_active_hash :category
- belongs_to_active_hash :condition
- belongs_to_active_hash :postage_type
- belongs_to_active_hash :prefectures
- belongs_to_active_hash :preparation_days
- belongs_to :seller, class_name: "User"


## item_purchases テーブル
| Column        | Type    | Options                        |
| ------------- | ------- | ------------------------------ |
| product       | integer | null: false, foreign_key: true |
| user          | integer | null: false, foreign_key: true |
| purchase_info | integer | null: false, foreign_key: true |

### Association

- belongs_to :user
- belongs_to :product
- belongs_to :purchase_info


## comments テーブル
| Column  | Type       | Options                        |
| ------- | ---------- | ------------------------------ |
| content | string     | null: false                    |
| user    | integer    | null: false, foreign_key: true |
| product | integer    | null: false, foreign_key: true |

### Association

- belongs_to :product
- belongs_to :user

## purchase_info テーブル

| Column        | Type       | Options                        |
| ------------- | ---------- | ------------------------------ |
| postal_code   | string     | null: false                    |
| prefectures   | integer    | null: false, foreign_key: true |
| city          | string     | null: false                    |
| address       | string     | null: false                    |
| building_name | string     |                                |
| phone_number  | string     | null: false                    |
| item_purchase | integer    | null: false, foreign_key: true |

### Association

- has_one_active_hash :prefectures
- has_one :item_purchase
```

ここでは、has_oneとbelongs_toの従属関係に注意しましょう。

外部キーが必要な場合はbelongs_toでアソシエーションが組まれていることが必要です。



最後に少しだけ感想ですが、初めての自力実装はめちゃくちゃ時間がかかりますが、楽しくてしかたなかったです。ただ、今日これをやるだけでも10時間ほどかかってしまったので挫折しないように頑張ります、、、