Railsで必須でないカラムのvalidationでハマった話


よっしゃー!正規表現バッチリ書いてRSpecでmodelのテスト通った!
ってなって喜んでしばらく放置してて久しぶりに人に見せるためにいじってみたら、あれ?新規登録できねえよってなってました。

今回の対象のmodelのマイグレーションファイル

class CreateClients < ActiveRecord::Migration[5.2]
  def change
    create_table :clients do |t|
      t.string :client_name1,null: false
      t.string :client_name2
      t.string :postcode
      t.string :add1
      t.string :add2
      t.string :add3
      t.string :tel
      t.string :fax
      t.string :client_person_in_charge
      t.string :mobile
      t.string :url
      t.string :email
      t.integer :client_rank_id
      t.integer :client_cat_id
      t.integer :closing_day_id
      t.integer :payment_day_id
      t.integer :payment_method_id
      t.references :user,foreign_key: true

      t.timestamps
    end
  end
end

mobileカラムとemailカラムに正規表現書いて達成感。

しかし、新規登録してみても何も起こらない

rollbackされてる。

Started POST "/clients" for ::1 at 2020-06-14 16:09:13 +0900
Processing by ClientsController#create as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"gdB/FJWD/yQj2xDKXjlKhq2gdJM6iQ1c1D3Hkm1z4THd2/FNJGWXqX2E6Odg3GJnAToUsxY4rNa7WfzFnX5Krg==", "client"=>{"client_name1"=>"PHP株式会社", "client_name2"=>"", "postcode"=>"", "add1"=>"", "add2"=>"", "add3"=>"", "tel"=>"", "fax"=>"", "client_person_in_charge"=>"", "mobile"=>"", "url"=>"", "email"=>"", "client_rank_id"=>"", "client_cat_id"=>"", "closing_day_id"=>"", "payment_day_id"=>"", "payment_method_id"=>"", "user_id"=>"1"}, "commit"=>"登録"}
  User Load (0.4ms)  SELECT  `users`.* FROM `users` WHERE `users`.`id` = 1 ORDER BY `users`.`id` ASC LIMIT 1
   /Users/honda/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/activerecord-5.2.4.2/lib/active_record/log_subscriber.rb:98
   (0.4ms)  BEGIN
   app/controllers/clients_controller.rb:11
  User Load (7.1ms)  SELECT  `users`.* FROM `users` WHERE `users`.`id` = 1 LIMIT 1
   app/controllers/clients_controller.rb:11
   (0.2ms)  ROLLBACK
   app/controllers/clients_controller.rb:11

ほへー。

原因はmodel以外あり得ない

もう思い当たる節はvalidationしかないので、modelをみる。

client.rb
  VALID_EMAIL_REGEX=/\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
  VALID_MOBILE_REGEX=/\A[0]+[789]+[0]\d{8}\z/
  validates :email,format: {with: VALID_EMAIL_REGEX,message: 'メールアドレスが正しくありません。'}
  validates :mobile,format: {with: VALID_MOBILE_REGEX,message: '携帯電話番号が正しくありません。'}

あ、validationで空文字許可がいるのか?

client.rb(修正後)
  VALID_EMAIL_REGEX=/\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
  VALID_MOBILE_REGEX=/\A[0]+[789]+[0]\d{8}\z/
  validates :email,format: {with: VALID_EMAIL_REGEX,message: 'メールアドレスが正しくありません。'},allow_blank: true
  validates :mobile,format: {with: VALID_MOBILE_REGEX,message: '携帯電話番号が正しくありません。'},allow_blank: true

presence: trueはいらない!って気を抜いてました。。。