【rails】deviseとdate_select使って歳の数だけウ●コ表示させる

「歳の数だけホニャララ」というのは何か理由をつけたい時によく使われる手法かと思います。
誕生日に歳の数だけ薔薇をプレゼントなんてのは、100本の薔薇だと予算オーバーとなるのでちょうどいい理由となりますよね。

さて、今回は年齢の数だけウ●コ表示させてみようかなと思い、実装できたので紹介します。

まずは完成した状態を見てみましょう。

![2a805aafa95a7d5480a38bff5ebbc13a (2).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/480700/2ad8a286-197e-3627-54ad-f89568d39941.gif)


では、どのように作ったのか書いていきます。

# [1]deviseを導入してdate_selectで誕生日を入力できるようにする
まずはdeviseをインストールし、誕生日をdata形式で入力できるよう実装します。

``gem 'devise'``をgemファイルに記載し、``$ bundle install``します。
　↓
``$ rails g devise:install``でdeviseをアプリにインストールします。
　↓
``$ rails g devise User``でmodelを作成しましょう。この際に誕生日を入力するためのカラムを作成します。

```ruby
# 2020XXXXXXXXXXX_devise_create_users.rb
# frozen_string_literal: true

class DeviseCreateUsers < ActiveRecord::Migration[5.2]
  def change
    create_table :users do |t|
      ## Database authenticatable
      t.string :nickname, null: false, default: ""
      t.date :birth_date,          null: false # ←こんな感じで追加します。
      t.string :email,              null: false, default: ""
      t.string :encrypted_password, null: false, default: ""

      ~~　省略　~~
end
```

上記のようにマイグレーションファイルにdate型のカラムを追加して、``$ rake db:migrate``します。
これで、値を入れるカラムができました。

次に、入力エリアを増やしてnicknameとbirth_dateを入力できるようにします。

``$ rails g devise:views``のコマンドでviewファイルを生成します。

今回はhamlで書いていくので、gemfileに``gem 'haml-rails'``を記載し、``$ bundle install``します。
そのあと、``$ rails haml:erb2haml``でerb→hamlに変換します。

hamlに変換した``/app/views/devise/registrations/new.html.haml``を下記のように編集します。

```haml
%h2 Sign up
= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f|
  = render "devise/shared/error_messages", resource: resource

  -# ~~~~ここから追加~~~~
  .field
    = f.label :nickname
    %br/
    = f.text_field :nickname, autofocus: true, autocomplete: "nickname"
  .field
    = f.label :birth_date
    %br/
    = f.date_select :birth_date, use_month_numbers: true,start_year: 1930, end_year: (Time.now.year - 10), default: Date.new(1989, 1, 1)
  -# ~~~~ここまで追加~~~~

  .field
    = f.label :email
    %br/
    = f.email_field :email, autofocus: true, autocomplete: "email"

  -# ~~~~ここから下は省略~~~~
```

上記のように追記することで、入力フォームは作成できました。
次に、カラムに保存できるように許可する記述を``/app/controllers/application_controller.rb``に記載します。

```application_controller.rb
  before_action :configure_permitted_parameters, if: :devise_controller?

  def configure_permitted_parameters
    devise_parameter_sanitizer.permit(:sign_up, keys: [:nickname, :birth_date])
  end
```

上記のように記載すると、``nickname``と``birth_date``をカラムに入れることを許可することができました。
これで、まずは誕生日を入力して保存できるところまでできました。

# [2]誕生日から年齢が表示できるようにする
まずは``$ rails g controller unkos index``で``unkos_controller.rb``と``/views/unkos/index.html.haml``を生成します。

date形式で保存された年月日から年齢を算出するための便利なgemを入れます。
gemfileに``gem 'happybirthday'``を記載して``$ bundle install``します。

それでは``/app/controllers/unkos_controller.rb``を下記のように追記します。

```unkos_controller.rb
class UnkosController < ApplicationController
  before_action :authenticate_user!

  require 'happybirthday'

  def index
    birthday = Happybirthday.born_on(current_user.birth_date)
    @birthday = birthday.age.years_old
  end
end
```

``before_action :authenticate_user!``は、ログインしてなければ、ログイン画面へリダイレクトさせるメソッドです。deviseを入れると使用できるメソッドです。

``require 'happybirthday'``は先ほど導入した``gem 'happybirthday'``を``unkos_controller.rb``で使用するための記述です。

``Happybirthday.born_on(current_user.birth_date)``では、現在ログイン中のユーザの誕生日を取得します。
``@birthday = birthday.age.years_old``にて、現在の年齢に置き換え``@birthday``に代入しています。

では、``/app/views/unkos/index.html.haml``を下記のようなコードを追記してください。

```index.html.haml
%h2
  = current_user.nickname + "さん"
%string
  = "現在#{@birthday}歳です。"
```
どうですか、これで年齢が表示できたでしょうか。

# [3]年齢の数だけウ●コを表示させる
では、画竜点睛になりますね。ウ●コを表示させるくだりです。
``/app/views/unkos/index.html.haml``に下記のような記述を追記してください。

```haml

%h2
  = current_user.nickname + "さん"
%string
  = "現在#{@birthday}歳です。"
%p それでは、歳の数だけウンコを表示します。
.unko_box{style: 'width: 550px; margin:0 auto'}
  - count = 0
  - loop do
    - count += 1
    = image_tag '****', alt: 'unko',  width: '50px', class: ''
    - if count == @birthday
      - break
```

``loop do``で繰り返しウ●コの画像を表示させるようにしまして、
``if count == @birthday``の箇所で、年齢の数でループ処理を止めています。
``= image_tag '****'``では画像の指定をしています。``/app/assets/images/``配下に画像を設置して、「****」にファイル名を記載してください。
これで、ウ●コが年齢分繰り返しされるわけですね。

# 応用編
ウ●コを年齢分表示させるって、一体どんなことに使うんだ？
そう思われる方もいらっしゃるかと思われますが、例えばこんな時に応用して使用できるかと思います。

## [応用1]歳の数だけ豆を表示する
<img width="717" alt="0f8aed49605f5a842815bacbc0a012a2 (2).png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/480700/072985da-77cc-1ba9-3502-a76c5bdb80d1.png">

節分の時期にどうでしょうか？

## [応用2]バースデーケーキーに歳の数だけロウソクを立てる
<img width="725" alt="f8ec92e8591aa1b61c8b1738181891a5 (2).png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/480700/15fff5a6-2402-3b5b-e3cb-5dff423a72f6.png">

一番実用的じゃないでしょうか？

# おわりに
いかがでしたでしょうか。
年齢の数だけ●●というのは、こじづけしがちな理由なので、
ぜひプログラミングでも実装してみてくださいね！

# 参考記事
[【rails】deviseで生年月日を登録する時のコツ](https://qiita.com/kaorioka09jm/items/671ebb9771d370500ae5)

[誕生日から年齢を計算するhappybirthday gemをリリースしました](https://takanamito.hateblo.jp/entry/2018/05/15/091820)

[Deviseの設定手順をまとめてみた。 その1　導入編](https://qiita.com/aplifyjp/items/ea0d9236d89fa24a7a1c)