yposiのブログ

Web開発日記

gem開発素人ながらsyameiを公開した話

4年前に作りかけた「syamei」を2020/07/16に公開しました。

syameiは一言で、法人格を除くことができます。

用途は名寄せでした。

パーフェクトRuby on Railsでおなじみの前島さん(https://willnet.jp/)にペアプロでご指導いただいて途中まで作っていました。 

公開するところまでいかず放っていたのをふと自宅の大掃除のタイミングで思い出し、つい最近公開しました。

なんだかんだ470のダウンロードをいただいて0じゃなくてよかったと思っております。

少し気持ちがよくなったこともあって、情報を公開しないと使われずに眠る可能性があるのでブログを書き始めたところです。

当時は、法人格を除くだけの機能だったのですが、リリースに向けてメソッドを追加しました。

  • 末尾の法人格を削除
  • 先頭の法人格を削除
  • 使用している法人格を取得
  • gemに登録している法人格の取得

 当時よりレベルもあがっていたので「【Ruby】gemの作り方から公開まで - Qiita」を参考にさせていただき微修正したくらいです。

qiita.com

 

Circle CIの設定等はあまりやってきていないので「Rubyのgemを公開しつつCircleCIでCI/CD(継続的インティグレーション/継続的デリバリー)を体験しよう - Qiita」からコードを参考にして微修正したくらいなのでまだまだ改良ポイントがあると思っております。

qiita.com

 

他の法人格がissueにあがったら是非対応したいと思うのでよろしくお願いします。

 

それと全く関係がないところで、fudo3というgemをリリースしますのでそこで記事を書けたらと思います。

fudo3は不動産でよく使われている計算系をまとめたものになります。

 

参考にしたサイト

RubyGems

ソースコード

IpValidatorを追加した

これはRailsアプリケーションの話です。
今回カラムにipを追加し、バリデーションを追加して欲しいとのことでした。
バリデーションはIPv4IPv6に対応して欲しいということでした。

この記事は、

  • Resolv::IPv4::Regex とResolv::IPv6::Regex というものが用意されていた
  • validatorを用意することでModelがスッキリする

という話ができたらと思います。

Resolv::IPv4::Regex とResolv::IPv6::Regex というものが用意されていた

正規表現って自分で書くとバグを生んだり、面倒だったりするのでまずはネットで調べると思うのですが、ありがたいことにRubyはいろんなものが用意されています。
Resolv::IPv4::Regex の存在を見つけました。
コンソールで実行してみると、

irb(main):001:0> Resolv::IPv4::Regex
=> /\A((?x-mi:0
               |1(?:[0-9][0-9]?)?
               |2(?:[0-4][0-9]?|5[0-5]?|[6-9])?
               |[3-9][0-9]?))\.((?x-mi:0
               |1(?:[0-9][0-9]?)?
               |2(?:[0-4][0-9]?|5[0-5]?|[6-9])?
               |[3-9][0-9]?))\.((?x-mi:0
               |1(?:[0-9][0-9]?)?
               |2(?:[0-4][0-9]?|5[0-5]?|[6-9])?
               |[3-9][0-9]?))\.((?x-mi:0
               |1(?:[0-9][0-9]?)?
               |2(?:[0-4][0-9]?|5[0-5]?|[6-9])?
               |[3-9][0-9]?))\z/

これはすごいですね!
IPv6も動くんじゃないか?と淡い期待をして実行してみました。
やっぱりいました。

irb(main):002:0> Resolv::IPv6::Regex
=> /
      (?:(?x-mi:\A
      (?:[0-9A-Fa-f]{1,4}:){7}
         [0-9A-Fa-f]{1,4}
      \z)) |
      (?:(?x-mi:\A
      ((?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4})*)?) ::
      ((?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4})*)?)
      \z)) |
      (?:(?x-mi:\A
      ((?:[0-9A-Fa-f]{1,4}:){6,6})
      (\d+)\.(\d+)\.(\d+)\.(\d+)
      \z)) |
      (?:(?x-mi:\A
      ((?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4})*)?) ::
      ((?:[0-9A-Fa-f]{1,4}:)*)
      (\d+)\.(\d+)\.(\d+)\.(\d+)
      \z))/x

さすがです。
これをいい感じに使用したバリデーターを作ろうと思って作りました。

# frozen_string_literal: true

class IpValidator < ActiveModel::EachValidator
  def validate_each(record, attribute, value)
    return true if Resolv::IPv4::Regex.match?(value) || Resolv::IPv6::Regex.match?(value)
    record.errors.add(attribute, :invalid_ip, options)
  end
end

作ったバリデーターを呼ぶには、

# == Schema Information
#
# Table name:hoges
#
#  id                 :bigint(8)        not null, primary key
#  ip                 :string(255)
#  created_at         :datetime         not null
#  updated_at         :datetime         not null
#

class Hoge < ApplicationRecord
  validates :ip, ip: true
end

「validates :ip, ip: true」これだけです。
バリデーターを作るところから真似してもらえると幸いです。

参考にしたページ