Ruby wasm validator demo

2024-06-04 ruby

ウェブアプリケーションのフロントもRubyでかけたら楽しそうだな、と思っていたら面白そうな記事を見つけたので参考にさせて頂いて、デモを作ってみました。

フォームのイメージ:

ruby-wasm-validator

Rubyのコードは以下の通りで、フォーム入力値の検証を行っています。

<script type="text/ruby">
require 'js'

def document
    @document ||= JS.global[:document]
end

def add_validator(id, regex, error_message)
    # input要素の後にエラーメッセージを表示する要素を準備
    input = document.getElementById(id)
    document.createElement('small').tap do |error|
        error[:id] = "#{id}_error"
        error[:className] = 'text-danger'
        input.insertAdjacentElement('afterend', error)
    end

    # input要素の入力値が変更されたときにエラーメッセージを表示する
    input.addEventListener 'input' do |e|
        error = document.getElementById("#{id}_error")
        cond = e[:target][:value].to_s.match?(regex)
        puts "regex: #{regex}, value: #{e[:target][:value]}, cond: #{cond}"
        error[:innerText] = cond ? '' : error_message
    end
end

add_validator('name', /\A[A-Za-z ]+\z/, '半角英字のみで入力してください')
add_validator('email', /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i, 'Emailが不正です')
add_validator('message', /\A.{10,}\z/, '10文字以上で入力してください')
</script>  

JavaScriptでも出来るじゃん、と言われたらそこまでなのですが、バックエンドがRailsで小規模なアプリの場合、2つの言語を行き来しなくて良いというのはちょっと嬉しいかもしれません。e[:target][:value].to_s みたいな(valueがStringでなくJSObjectで返る)とこは慣れないと難しそうだなと感じるのと、エラーメッセージが分かりにくく(rubywasmのスタックトレースが出てくる)、デバッグし辛いというあたりが(現時点の)ディスアドバンテージかな。Mac+Chrome環境で試す限り、Rubyのロードは思ったほど重くない気がします(キャッシュが効いてる?)。