0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

ウィザード形式でユーザ登録のフォームを作成してみた③-1 〜バリデーション〜

0
Last updated at Posted at 2020-06-08

【この記事の説明】

現在、私はプログラミングスクールでプログラミング(主にRuby)の勉強をしています。
そして、その一環でチーム開発(メルカリもどきのサイト作成)を行っており、私はその中で記事のタイトルにあるように、ウィザード形式でユーザの登録ができるようにする作業を担当致しました。
又、スクールからの指示で、この登録フォームにはdeviseを使用するようにとのことでした。

この記事は、その担当作業についてまとめたものになります。

【作業】

ここから私が行った作業(そこで困ったこと)を記事として記載していこうと思います
※この記事では、バリデーションについて記載したいと思います

バリデーション

必要部分のみ抜粋
def new_profileaddresses
    unless @user.valid?
      flash.now[:alert] = @user.errors.full_messages
      render :new and return
    end
end

def new_deliveryaddresses
    unless @profileaddress.valid?
      flash.now[:alert] = @profileaddress.errors.full_messages
      render :new_profileaddresses and return
    end
end

def create
    unless @deliveryaddress.valid?
      flash.now[:alert] = @deliveryaddress.errors.full_messages
      render :new_deliveryaddresses and return
    end
end

上記はunless xxx.valid?~endにより、バリデーションに引っかかった場合はrenderによってviewに飛ばされるようになっていることを記述しています

このvalid?のバリデーションはmodelに記述することで発動します
その為、私は下記のようにmodelに記述し、バリデーションをかけました

model

/app/models/user.rb
class User < ApplicationRecord
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :validatable,password_length: 7..128
         
  validates :nickname, presence: true
  validates :family_name, presence: true
  validates :given_name, presence: true
  validates :family_name_kana, presence: true
  validates :given_name_kana, presence: true
  validates :birthday, presence: true
  
  has_one :profileaddress, dependent: :destroy
  has_one :deliveryaddress, dependent: :destroy

  # パスワード英字数字1文字かつ7文字以上のバリデーション↓
  validate :password_complexity
  # 全角のバリデーション↓
  validate :name_em
  validate :name_kana_em
  # メールアドレスのバリデーション↓
  validate :valid_email?


  def valid_email?
    return if email.blank? || email =~ /^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/
    # blank?はblankであれば"true"でblankでなければ"flase"を返す
    # ||は"または"であり左側が"false"なら右側を"return"する
    # つまり"email.blank?"が"false(ブランクではない)"場合、"email"を正規表現にかけるということになる
  end
  def password_complexity
    # Regexp extracted from https://stackoverflow.com/questions/19605150/regex-for-password-must-contain-at-least-eight-characters-at-least-one-number-a
    return if password.blank? || password =~ /^(?=.*?[a-zA-Z])(?=.*?[0-9]).{7,70}$/
    # blank?-値がない状態がture
    errors.add :password, "は英字と数字をそれぞれ1文字以上含める必要があります"
    # password.blank? || password =~ のどちらも"false"だからエラーになり、エラー表示される
  end

  def name_em
    if !(family_name =~ /^[ぁ-んァ-ン一-龥]/)
      if !(given_name =~ /^[ぁ-んァ-ン一-龥]/)
        errors.add :family_name, "は全角で入力してください"
        errors.add :given_name, "は全角で入力してください"
      else
        errors.add :family_name, "は全角で入力してください"
      end
    elsif !(given_name =~ /^[ぁ-んァ-ン一-龥]/)
      errors.add :given_name, "は全角で入力してください"
    else
      return
    end
  end

  def name_kana_em
    if !(family_name_kana =~ /^([ァ-ン]|ー)+$/)
      if !(given_name_kana =~ /^([ァ-ン]|ー)+$/)
        errors.add :family_name_kana, "は全角カタカナで入力してください"
        errors.add :given_name_kana, "は全角カタカナで入力してください"
      else
        errors.add :family_name_kana, "は全角カタカナで入力してください"
      end
    elsif !(given_name_kana =~ /^([ァ-ン]|ー)+$/)
      errors.add :given_name_kana, "は全角カタカナで入力してください"
    else
      return
    end
  end
end

Userモデルに関しては、deviseに元々備わっているものも利用している為、このような形になりました
下の2つのモデルはdeviseが関係ないので、全て私がバリデーションを記述した形になります

/app/models/profileaddress.rb
class Profileaddress < ApplicationRecord
  belongs_to :user, optional: true
  # optional: true は外部キーがnullであることを許可するオプション

  validate :zipcode
  # 郵便番号のバリデーション(ハイフンなし7桁)↑
  validate :full_width_city
  validate :full_width_address
  validate :full_width_building
  # 全角のみ入力設定(半角ではない設定)↑
  def zipcode
    return if postal_code.blank? || postal_code =~ /\A\d{7}\z/
    @error_name = I18n.t(User.human_attribute_name(:postal_code))
    # ja.ymlからデータを引っ張ってきている↑
    errors.add @error_name, "は不当な値です。ハイフンなし、7桁の数字で入力してください"
  end

  def full_width_city
    return if city.blank? || city =~ /^[^ -~。-゚]*$/
    @error_name = I18n.t(User.human_attribute_name(:city))
    errors.add @error_name, "は全角で入力してください"
  end
  def full_width_address
    return if address.blank? || address =~ /^[^ -~。-゚]*$/
    @error_name = I18n.t(User.human_attribute_name(:address))
    errors.add @error_name, "は全角で入力してください"
  end
  def full_width_building
    return if building.blank? || building =~ /^[^ -~。-゚]*$/
    @error_name = I18n.t(User.human_attribute_name(:building))
    errors.add @error_name, "は全角で入力してください"
  end

  enum prefecture:{
    ーーー:0,北海道:1,青森県:2,岩手県:3,宮城県:4,秋田県:5,山形県:6,福島県:7,
    茨城県:8,栃木県:9,群馬県:10,埼玉県:11,千葉県:12,東京都:13,神奈川県:14,
    新潟県:15,富山県:16,石川県:17,福井県:18,山梨県:19,長野県:20,
    岐阜県:21,静岡県:22,愛知県:23,三重県:24,
    滋賀県:25,京都府:26,大阪府:27,兵庫県:28,奈良県:29,和歌山県:30,
    鳥取県:31,島根県:32,岡山県:33,広島県:34,山口県:35,
    徳島県:36,香川県:37,愛媛県:38,高知県:39,
    福岡県:40,佐賀県:41,長崎県:42,熊本県:43,大分県:44,宮崎県:45,鹿児島県:46,沖縄県:47
  }
  
end
/app/models/deliveryaddress.rb
class Deliveryaddress < ApplicationRecord
  # validates :family_name, presence: true
  # ↑のようにバリデーションすると日本語化できないので↓のメソッドでバリデーションしてます

  belongs_to :user,optional: true

  # 全角(&空白)のバリデーション↓
  validate :name_em
  validate :name_kana_em

  # 決まった桁の数字を入力するバリデーション↓
  validate :zipcode
  validate :phone_number_check

  # 全角のみ入力設定(半角ではない設定)↓
  validate :full_width_city
  validate :full_width_address
  validate :full_width_building
  

  enum prefecture:{
    北海道:1,青森県:2,岩手県:3,宮城県:4,秋田県:5,山形県:6,福島県:7,
    茨城県:8,栃木県:9,群馬県:10,埼玉県:11,千葉県:12,東京都:13,神奈川県:14,
    新潟県:15,富山県:16,石川県:17,福井県:18,山梨県:19,長野県:20,
    岐阜県:21,静岡県:22,愛知県:23,三重県:24,
    滋賀県:25,京都府:26,大阪府:27,兵庫県:28,奈良県:29,和歌山県:30,
    鳥取県:31,島根県:32,岡山県:33,広島県:34,山口県:35,
    徳島県:36,香川県:37,愛媛県:38,高知県:39,
    福岡県:40,佐賀県:41,長崎県:42,熊本県:43,大分県:44,宮崎県:45,鹿児島県:46,沖縄県:47
  }

  def name_em
    @error_name1 = I18n.t(User.human_attribute_name(:family_name))
    @error_name2 = I18n.t(User.human_attribute_name(:given_name))
    if !(family_name =~ /^[ぁ-んァ-ン一-龥]/)
      if !(given_name =~ /^[ぁ-んァ-ン一-龥]/)
        errors.add @error_name1, "は全角で入力してください"
        errors.add @error_name2, "は全角で入力してください"
      else
        errors.add @error_name1, "は全角で入力してください"
      end
    elsif !(given_name =~ /^[ぁ-んァ-ン一-龥]/)
      errors.add @error_name2, "は全角で入力してください"
    else
      return
    end
  end

  def name_kana_em
    @error_name3 = I18n.t(User.human_attribute_name(:family_name_kana))
    @error_name4 = I18n.t(User.human_attribute_name(:given_name_kana))
    if !(family_name_kana =~ /^([ァ-ン]|ー)+$/)
      if !(given_name_kana =~ /^([ァ-ン]|ー)+$/)
        errors.add @error_name3, "は全角カタカナで入力してください"
        errors.add @error_name4, "は全角カタカナで入力してください"
      else
        errors.add @error_name3, "は全角カタカナで入力してください"
      end
    elsif !(given_name_kana =~ /^([ァ-ン]|ー)+$/)
      errors.add @error_name4, "は全角カタカナで入力してください"
    else
      return
    end
  end

  def phone_number_check
    return if phone_number.blank? || phone_number =~ /\A\d{10,11}\z/
    @error_name5 = I18n.t(User.human_attribute_name(:phone_number))
    errors.add @error_name5, "は不当な値です。ハイフンなし、10桁,又は11桁の番号で入力してください"
  end

  def zipcode
    return if postal_code =~ /\A\d{7}\z/
    @error_name6 = I18n.t(User.human_attribute_name(:postal_code))
    errors.add @error_name6, "はハイフンなし、7桁の数字で入力してください"
  end

  def full_width_city
    if city.blank? 
      @error_name7 = I18n.t(User.human_attribute_name(:city))
      errors.add @error_name7, "は全角で入力してください"
    elsif !(city =~ /^[^ -~。-゚]*$/)
      @error_name7 = I18n.t(User.human_attribute_name(:city))
      errors.add @error_name7, "は全角で入力してください"
    else
      return
    end
  end

  def full_width_address
    if address.blank?
      @error_name8 = I18n.t(User.human_attribute_name(:address))
      errors.add @error_name8, "は全角で入力してください"
    elsif !(address =~ /^[^ -~。-゚]*$/)
      @error_name8 = I18n.t(User.human_attribute_name(:address))
      errors.add @error_name8, "は全角で入力してください"
    else
    end
  end
  def full_width_building
    return if building.blank? || building =~ /^[^ -~。-゚]*$/
    @error_name9 = I18n.t(User.human_attribute_name(:building))
    errors.add @error_name9, "は全角で入力してください"
  end
end

必須と任意
今回の入力フォームには、入力必須のフォームと任意のフォームがあり、バリデーションはそれに合わせて作成しました
例えばdeliveryaddress.rbの場合は下記のような形になります
addressは入力必須項目
buildingは入力任意項目

必要部分のみ抜粋

  def full_width_address
    if address.blank?
      @error_name8 = I18n.t(User.human_attribute_name(:address))
      errors.add @error_name8, "は全角で入力してください"
      # 空白ならエラーを表示する
    elsif !(address =~ /^[^ -~。-゚]*$/)
      @error_name8 = I18n.t(User.human_attribute_name(:address))
      errors.add @error_name8, "は全角で入力してください"
      # 正規表現にあっていない場合はエラーを表示する
    else
      # それ以外はバリデーション通過
    end
  end
  def full_width_building
    return if building.blank? || building =~ /^[^ -~。-゚]*$/
     # ブランク又は正規表現通り(この場合は半角ではない、つまり全角)だったらtrueでそのまma
     # ブランクでもなく、正規表現通りでもない(つまりは半角)だったらどちらもfalseでエラーとなり、エラー表示対象
    @error_name9 = I18n.t(User.human_attribute_name(:building))
    errors.add @error_name9, "は全角で入力してください"
  end

【次の記事】

バリデーションをかければ、データ(一時)保存する時も、不必要なデータが入ることは無くなります
しかし、そこにエラー表示がないと入力しているユーザは何故データが保存されないのかわからず、困ってしまいます
その為、エラー表示はユーザの為にも必要なものです
次の記事では、そのエラー表示について記載したいと思います

次の記事 → ウィザード形式でユーザ登録のフォームを作成してみた③-2 〜バリデーション(エラー表示)〜

【参考】

form用正規表現判定/備忘
deviseでパスワードの最低文字数を変更する方法。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?