【rails】deviseで生年月日を登録する時のコツ


railsにて通販サイトのような物を作成する課題に勤しんでおり、
devise使用してユーザー管理を実装しました。
いきあたりばったりで実装して出したエラーを紹介します。

[1]date_selectを使用する

date_selectとはなんぞや。
これはフォームの入力形式のようなもので、生年月日や日時登録に非常に便利なものになります。

devise/registrations/new.html.haml
  .content_wrapper
    %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 :name
        %br/
        = f.text_field :name, autofocus: true, autocomplete: "name"

      -#  生年月日の入力エリア
      .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)

西暦と月日を入力するプルダウンが出現します。
プルダウンを3つ用意すると思いきや、「date_select」を使用することで、3つまとめて出てきてくれます。


レコードに入るのはこんな感じの形式になります。

普通のプルダウンはselectを使用しますが、それだと入力する項目を自分で手書きしなければイケナイためとてつもなく面倒です。

コピペで実装できるようにしてくれているページもありますが、
大量のコードを書くことに代わりはありません。

参考
【コピペ】HTMLフォームのselect項目まとめ(生年月日・年齢・都道府県・職業)

[2]データ型はdateを使用する

テーブルを追加するときに、生年月日カラムのデータ型は「date」となるようにする。
でないと、hamlにf.date_selectを記載した時点でデータ型違うよ的なエラーが出ます。
マイグレーションファイルは下記のようになっています。

20191228100045_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 :name,              null: false, default: ""
      t.date :birth_date,          null: false
# 省略
    end
# 省略
  end
end

詳しい追加方法は下記の記事を参考に!

Deviseの設定手順をまとめてみた。 その1 導入編

[3]マイグレートファイルにdefault: ""を書かない

なんとなくtextやstringのような感じで、データ型だけdateにしておけばマイグレートできるだろうと思ったら、default: ""が書いてあることによってマイグレートできませんでした。
[2]でも書きましたが、下記のようにdefault: ""なしにしないと、$ rake db:migrateのときにコケます。
プルダウンで入力するため、default: ""って矛盾してるからマイグレートデキナイヨ!ってことです。

20191228100045_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 :name,              null: false, default: ""
      t.date :birth_date,          null: false
# 省略
    end
# 省略
  end
end

[4]deviseを日本語対応したらuse_month_numbers: trueを追加

月のところの表示を[Jan.][Feb.]などの英語表記にならないようにできます。

devise/registrations/new.html.haml
= f.date_select :birth_date, use_month_numbers: true, ~省略~

何度も擦られてますが、この部分ですね。

[5]入力範囲を絞ろう

devise/registrations/new.html.haml
  .content_wrapper
    %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 :birth_date
        %br/
        = f.date_select :birth_date, use_month_numbers: true,
          start_year: 1930, #入力値の開始位置(西暦)
          end_year: (Time.now.year - 10), #入力値の終了位置(現在から10年前に指定)
          default: Date.new(1989, 1, 1) #デフォルトで表示されている値

入力範囲を絞らないで実装すると、西暦部分が際限なく出てしまうため、このようにして絞ってあげるとユーザーが選択しやすくなります。

例えば、18才以上でないと登録できないサイトだった場合、end_year: (Time.now.year - 18)とすることで、18才以下の入力を制限することが可能かと思います。
まぁ、そんなことくらいじゃ欲望は(以下略

おわりに

めっちゃ基本的というか、普通にやってたら出ないエラー出したので、メモがてら記事書いてみました。
コツっていうか凡ミス対策ですね。

deviseで誕生日を入力する簡単なミニアプリを作ってみたい方は下記の記事をどうぞ!(PR)
【rails】deviseとdate_select使って歳の数だけウ●コ表示させる