@k12da (K Yoshida)

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

ハイフン付きの電話番号をハイフンなしに変換したい

解決したいこと

ウェブアプリの新規登録画面の電話番号入力欄で、ハイフンが入力されたら削除して、ハイフンなしで電話番号が登録されるようにしたい。

※今回はAPIモードで作成。

発生している問題・エラー

Officeモデルを作成し、下記の10〜11桁の電話番号のバリデーションを加えたが、これが動作する前にハイフン付き電話番号を変換したいが、実装方法が思い浮かばない...

office.rb
class Office < ApplicationRecord

  validates :tell, format: { with: /\A\d{10,11}\z/, message: '電話番号は有効な値ではありません'}

end

なお、現状ではPostmanで上記のバリデーションで設定したmessageの内容が返ってくる。
スクリーンショット 2022-11-21 19.36.45.png

自分で試したこと

コントローラーのprivateに下記のメソッドを作成し、電話番号のハイフンをgsubメソッドで削除するロジックを書いたが、動作しない。
controller側で受け取った時にハイフンを外す処理を入れてその後、保存処理をすればうまくいくはずと考えています。

offices_controller.rb

   def create
     @office = Office.create(office_params)
     if @office.save     
      render json: { status: 'SUCCESS', data: @office }
     else
     render json: { status: 'ERROR', data: @office.errors }
     end
   end


private
 def convert_tell(office_params)
   office_params.match?(/\A\d{1,4}-\d{1,4}-\d{3,4}\z/).gsub(/-/, '')
 end

 def office_params
   params.permit(:name, :address, :tell, :fax)
 end

参考記事
https://qiita.com/shimadama/items/f389f0c8b999038d40e3

0 likes

2Answer

tellがハイフン無しで矯正させたいというのはcontroller側の責務ではなく、Officeモデル側にあったほうがシンプルになりそうです。
モデルに落とし込んでいれば単体テストも楽にかけますし、rails consoleからとりあえず動作確認もしやすいです。

class Office < ApplicationRecord

+  before_validation :remove_dashes
  validates :tell, format: { with: /\A\d{10,11}\z/, message: '電話番号は有効な値ではありません'}

+  private
+  
+  def remove_dashes
+    self.tell = tell.scan(/\d/).join
+  end
end

2Like

Comments

  1. @k12da

    Questioner

    ありがとうございます!

バリデーションが処理される優先順位を意識する必要があると思われます。
※以下は最新の記事ではないので必要に応じて
 公式ドキュメントやGitHubのソースを追ってみてください

もし、上記以外で
「入力された段階で入力チェック及び置換を行う」ということであれば
JavaScriptなどで「フロントサイドのバリデーション」を実装する必要があります。

1Like

Comments

  1. @k12da

    Questioner

    ありがとうございます。上の記事を参考に修正してみました。

    ```offices_controller.rb
    def create
    @office = Office.create(office_params)
    if @office.valid?(:step1)
    convert_tell && @office.save
    elsif @office.valid?(:step2) && @office.save
    render json: { status: 'SUCCESS', data: @office }
    else
    render json: { status: 'ERROR', data: @office.errors }
    end
    end

    private

    def convert_tell
    params[:tell].gsub(/-/, '')
    end


    ```

    ```office.rb
    class Office < ApplicationRecord

    belongs_to :municipality

    validates :name, presence: true
    validates :address, presence: true

    with_options on: :step1 do
    validates :tell, presence: true, format: { with: /\A\d{1,4}-\d{1,4}-\d{3,4}\z/, message: '電話番号は有効な値ではありません' }
    end

    with_options on: :step2 do
    validates :tell, presence: true, format: { with: /\A\d{10,11}\z/, message: '電話番号は有効な値ではありません'}
    end
    end

    ```

    if @office.valid?(:step1)~の時にpostmanで204エラーになりました。(elsifは問題なく動作しています)

    これを書く前に、「NoMethodError: undefined method `gsub' for #<Office id: 55」というエラーが出ました。
    コントローラーのcreateで下記のように書いてました。
    ```
    if @office.valid?(:step1).gsub(/-/, '') && @office.save
    ```
    gsubに対して、メソッドの定義が必要なのだと思いますが、
    paramsの値(:tell)に対して、どのようなメソッドを定義しなければいけないでしょうか。

Your answer might help someone💌