概要
今更ではありますが、gem作って外部公開するということをやってみたくてやりました。
公開したgemは日付の表示形式を整えるメソッドを自動でやってくれる簡単なものです。まだ改善の余地があるのですが
作成したgemはこちらです。
環境
- ruby 2.3.1
- rails 4.2.7
開発の流れ
1.gemの雛形を作成
こちらを参考にしました。
> bundle exec rails plugin new dog_formatter
2.gemの中身の作成
2-1.dog_formatter.gemspecの編集
依存が必要だったり開発時に使ったりするgemを追記します。また今回作成するgemに関する情報も記述します。
1 $:.push File.expand_path("../lib", __FILE__)
2
3 # Maintain your gem's version:
4 require "dog_formatter/version"
5
6 # Describe your gem and declare its dependencies:
7 Gem::Specification.new do |s|
8 s.name = "dog_formatter"
9 s.version = DogFormatter::VERSION
10 s.authors = ["ホゲホゲホゲ"]
11 s.email = ["hogehoge@gmail.com"]
12 s.homepage = ""
13 s.summary = "日付けのFormatter"
14 s.description = "日付けのFormatterをするgem"
15 s.license = "MIT"
16
17 s.files = Dir["{app,config,db,lib}/**/*", "MIT-LICENSE", "Rakefile", "README.rdoc" ]
18 s.test_files = Dir["test/**/*"]
19
20 s.add_dependency "rails", "~> 4.2.6"
21
22 s.add_development_dependency "sqlite3"
23 s.add_development_dependency "ridgepole"
24 end
2-2. lib/dog_formatter/model.rb
を作成し編集
今回のgemは「~_at」 って名前のカラムがあったら、それのカラムに対し自動的に「~_at_ymd」とい名前のメソッドを追加するgemなのでActiveRecordを拡張するという意味からmodelって名前のクラスを作成してそこに書くことにしました。
1 module DogFormatter
2 module Model
3 extend ActiveSupport::Concern
4
5 included do
6 end
7
8 def method_missing(method_name, *_args, &_block)
9 method_name_suffix = matched_method_name_suffix(method_name.to_s)
10 return unless method_name_suffix
11
12 suffix_pattern = Regexp.new(method_name_suffix)
13 attribute_name_except_format_value = method_name.to_s.sub!(suffix_pattern, '')
14
15 return unless exist_column?(attribute_name_except_format_value)
16
17 formatted_with_method_name_suffix(attribute_name_except_format_value, method_n ame_suffix)
18 end
19
20 private
21 def format_suffixs
22 ['_ymd', '_ymd_ja', '_ym', '_ym_ja']
23 end
24
25 def matched_method_name_suffix(method_name)
26 format_suffixs.each { |suffix| return suffix if method_name.end_with?(suffix) }
27 end
28
29 def date_columns
30 self.class.column_names.select { |column_name| column_name =~ /.*_at/ } # TODO: ちゃんとデータの型も見るようにする
31 end
32
33 def exist_column?(attribute_name)
34 date_columns.include?(attribute_name)
35 end
36
37 def formatted_with_method_name_suffix(attribute_name, method_name_suffix)
38 read_attribute(attribute_name).strftime(format_text(method_name_suffix))
39 end
40
41 def format_text(method_name_suffix)
42 # TODO: 設定ファイルなどに外出ししたものを読み込む形式に変更する
43 case method_name_suffix
44 when '_ymd'
45 '%Y/%m/%d'
46 when '_ymd_ja'
47 '%Y年%m月%d日'
48 when '_ym'
49 '%Y/%m'
50 when '_ym_ja'
51 '%Y年%m月'
52 else
53 raise '変換できません。該当する日付形式がありません'
54 end
55 end
56 end
57 end
58
59 ActiveRecord::Base.send :include, DogFormatter::Model
3.test
テストではActiveRecordを使って実際の動きを確認したいので、ridgepoleを使って簡単にテーブルを作ってやりました。
3−1.テーブル作成
ridgepoleのスキーマファイルは次のように書き、ridgepoleコマンドを実行させてテーブル作成しました。(詳細は省略)
1 create_table "users", force: :cascade do |t|
2 t.string "name", limit: 255
3 t.datetime "created_at"
4 t.datetime "updated_at"
5 end
4.githubへの登録
githubにpush。(詳細は省略)
5.rubygemへの登録
こちらを参照させていただきました。
5-1. rubygemにsign up
こちらでe-mail/handle名/password(10文字以上)を入れて登録
5-2. rubygemのapiアクセスキーの登録
curl -u Handle名 https://rubygems.org/api/v1/api_key.yaml > ~/.gem/credentials; chmod 0600 ~/.gem/credentials
6.いざ、release!
ここまできたらいよいよリリースです。
> bundle exec rake release
使ってみる
思ったような動作をしている
1 require 'dog_formatter/model'
2
3 class User < ActiveRecord::Base
4 end
user.created_at_ymd
=> "2016/11/04"
user.created_at_ymd_ja
=> "2016年11月04日"
user.created_at_ym
=> "2016/11"
user.created_at_ym_ja
=> "2016年11月"
所感
他でも使えるような共通処理ははgem化すると良いなとは思っていたので、これからまた色々と作ってみたいと思いました。