FakerとRailsタスクについて学ぶ_100DaysOfCodeチャレンジ5日目(Day_5:#100DaysOfCode)

## はじめに
この記事はTwitterで人気のハッシュタグ`#100DaysOfCode`をつけて、
100日間プログラミング学習を続けるチャレンジに挑戦した5日目の記録です。

## 動作環境
* ruby 2.4.1
* Rails 5.0.1

## 現在学習している内容のリポジトリ
https://github.com/yuta-ushijima/notebook-api-on-rails

## 本日学んだこと
* Fakerの使い方
* Railsタスクの作成方法

## Fakerとは？

Fakerとは偽造者という意味。その名の通りダミーデータを生成してくれるので、テストや動作確認などを行いたい時に便利です。

### 公式リポジトリ

[faker](https://github.com/stympy/faker)

## GemFileにFakerを追記

```
#Gemfile

gem install faker
```

`bundle install`を実行

これでFakerが使えるようになりました。

## Railsタスクを使ってダミーデータを作成してみる。

Railsタスクとは、`rails`コマンドで実行できるタスクランナーのこと。普段使っている`rails db:migrate`や`rails db:create`もRailsタスクの一つ。

`rails -T`で現在使用できるすべてのタスクを確認することができます。

ターミナルでRailsプロジェクトのあるディレクトリで`rails -T`と実行してみます。

```
rails about                          # List versions of all Rails frameworks and the environment
rails app:template                   # Applies the template supplied by LOCATION=(/path/to/template) or URL
rails app:update                     # Update configs and some other initially generated files (or use just update:configs or upda...
rails db:create                      # Creates the database from DATABASE_URL or config/database.yml for the current RAILS_ENV (us...
rails db:drop                        # Drops the database from DATABASE_URL or config/database.yml for the current RAILS_ENV (use ...
rails db:environment:set             # Set the environment value for the database
rails db:fixtures:load               # Loads fixtures into the current environment's database
rails db:migrate                     # Migrate the database (options: VERSION=x, VERBOSE=false, SCOPE=blog)
rails db:migrate:status              # Display status of migrations
rails db:rollback                    # Rolls the schema back to the previous version (specify steps w/ STEP=n)
rails db:schema:cache:clear          # Clears a db/schema_cache.dump file
rails db:schema:cache:dump           # Creates a db/schema_cache.dump file
rails db:schema:dump                 # Creates a db/schema.rb file that is portable against any DB supported by Active Record
rails db:schema:load                 # Loads a schema.rb file into the database
rails db:seed                        # Loads the seed data from db/seeds.rb
rails db:setup                       # Creates the database, loads the schema, and initializes with the seed data (use db:reset to...
rails db:structure:dump              # Dumps the database structure to db/structure.sql
rails db:structure:load              # Recreates the databases from the structure.sql file
rails db:version                     # Retrieves the current schema version number
rails dev:cache                      # Toggle development mode caching on/off
rails dev:setup                      # 開発環境設定
rails initializers                   # Print out all defined initializers in the order they are invoked by Rails
rails log:clear                      # Truncates all/specified *.log files in log/ to zero bytes (specify which logs with LOGS=tes...
rails middleware                     # Prints out your Rack middleware stack
rails notes                          # Enumerate all annotations (use notes:optimize, :fixme, :todo for focus)
rails notes:custom                   # Enumerate a custom annotation, specify with ANNOTATION=CUSTOM
rails restart                        # Restart app by touching tmp/restart.txt
rails routes                         # Print out all defined routes in match order, with names
rails secret                         # Generate a cryptographically secure secret key (this is typically used to generate a secret...
rails stats                          # Report code statistics (KLOCs, etc) from the application or engine
rails test                           # Runs all tests in test folder
rails test:db                        # Run tests quickly, but also reset db
rails time:zones[country_or_offset]  # List all time zones, list by two-letter country code (`rails time:zones[US]`), or list by U...
rails tmp:clear                      # Clear cache and socket files from tmp/ (narrow w/ tmp:cache:clear, tmp:sockets:clear)
rails tmp:create                     # Creates tmp directories for cache, sockets, and pids
```

ズラーっとタスクが一覧で表示されていますね。

ちなみに開発環境設定という日本語の説明になっているRailsタスクはオリジナルで作成したものです。

それでは早速Railsタスクの作成方法についてみていきましょう。

## Generateコマンドでタスクファイルを生成する

オリジナルのタスクはモデルやコントローラーを作成するときと同様に、`generate`コマンドを使用します。

例えば、開発環境の構築という意味で`dev setup`というタスクを作成したい場合は、

`rails g task dev setup`

のようにターミナルで叩きます。

```
Running via Spring preloader in process 85015
      create  lib/tasks/dev.rake
```

実行すると、上記のように`lib`ディレクトリ配下に`tasks`というディレクトリが作成され、その中に`dev.rake`というファイルが作成されます。

ファイルを開くとデフォルトで以下のような記述がされています。

```
namespace :dev do
  desc "TODO"
  task setup: :environment do
  end
end
```

あとはsetupブロックの中に実行したい処理を書いてあげればOK。

作成したタスクを呼び出すときは、実行したいタスクを

`rails dev:setup`のようにターミナルで叩けばOKです。

なお、ファイル内に`namespace :dev`とあるように、名前空間ごとにそれぞれのタスクを切り替えることができるようになっています。

## Fakerを使った`set up`タスクを作成

さて、ここからはFakerを使ってダミーデータを作成する`setup`タスクを実装してみたいと思います。

まずは作成したファイルから。

```
namespace :dev do
  desc "開発環境設定"
  task setup: :environment do

    puts "説明文のダミーデータ生成中..."

    kinds = %w(Goodmorning! Hello! Goodbye!)

    kinds.each do |kind|
      Kind.create!(
        description: kind
      )
    end
    puts "説明文のダミーデータ登録完了！"

    ################################

    puts "Contactテーブルのダミーデータ生成中..."
    100.times do |generate|
      Contact.create!(
        name: Faker::Name.name,
        email: Faker::Internet.email,
        birthdate: Faker::Date.between(65.days.ago, 18.years.ago),
        kind: Kind.all.sample
       )
    end
    puts "Contactテーブルのダミーデータ登録完了！"

    ################################

    puts "Phoneテーブルのダミーデータ生成中..."
    Contact.all.each do |contact|
      Random.rand(5).times do |i|
        phone = Phone.create(number: Faker::PhoneNumber.cell_phone)
        contact.phones << phone
        contact.save!
      end
    end
    puts "Phoneテーブルのダミーデータ登録完了！"

    
  end
end
```


処理自体は特別難しいものはないと思いますが、注目したいのがFakerを使ったヘルパーたち。

ファイル内では、

* Faker::Name.name
* Faker::Internet.email
* Faker::PhoneNumber.cell_phone

このようなヘルパーが使われており、それぞれ名前やメールアドレス、電話番号のダミーデータを作成してくれます。

Timesメソッドを組み合わせることで、その回数分実行できるので、大量に欲しい場合は`100.times`のようにして実行すれば100件分のダミーデータが作成されます。

まあ、ループ処理なので当たり前ですけどね。

ちなみに、Fakerはロケールの設定を日本語にすると、`Faker::Name.name`を実行して作成されたダミーデータがちゃんと日本語の名前になってくれるので便利です。

```
# JSONデータ
 {
        "id": 1,
        "name": "竹内 悠斗",
        "email": "lola@hane.name",
        "birthdate": "2008-10-10",
        "created_at": "2018-06-20T14:02:48.678Z",
        "updated_at": "2018-06-20T14:02:48.678Z",
        "kind_id": 3,
        "birthday": "2008/10/10"
    },
    {
        "id": 2,
        "name": "山本 直樹",
        "email": "abraham.ortiz@ebert.co",
        "birthdate": "2003-07-12",
        "created_at": "2018-06-20T14:02:48.693Z",
        "updated_at": "2018-06-20T14:02:48.693Z",
        "kind_id": 2,
        "birthday": "2003/07/12"
    },
・
・
・
```
Faker公式リポジトリでは、READMEにたくさんのヘルパーが紹介されています。

ベーター版のアプリなどを作成するときなどに便利だと思うので、興味がある人は活用してみてください。

## 参考リンク

https://github.com/stympy/faker