仕事で使うためにgemを作ったったという話です。
自分が担当している製品は、情報を収集して、それを集計して…みたいなことをよくやるのですが、その時の課題が『表記揺れ』だったりします。よくありますよねー。ASUSのことをどう読むのか?みたいな問題。いくら公式が『エイスース』と言っても、『エーサス』『アーサス』『アサス』などと書かれることはあるわけです。情報を収集するときに『エーサス』と書かれているものは『エイスース』として認識したい!ということですが、そのためにはニックネームを管理する仕組みが必要です。
そこで、ニックネームを管理するためのgem imyou(異名)を作りました。
github.com
gemの名前はニックネームを被りにくい日本語にしたものです。Rails 4と5に対応しています。
使い方
使い方はREADMEに書いていますが、一応説明を。
インストール
Gemfileに書いてbundle install
してください。
gem 'imyou'
imyou用のテーブルを生成する必要があります。generatorを定義してあるので、それを使ってmigration用のファイルを生成して、マイグレーションしてください。
$ rails generate imyou:migration
$ rails db:migrate
Userモデル
Userモデルには、nameカラムがあるとします。
class User < ApplicationRecord
has_imyou
end
ニックネーム検索するときの対象として、nameカラムも含めたい場合は以下のように。
class User < ApplicationRecord
has_imyou :name
end
実際に使う
登録系
登録は、add_nickname
メソッドと、nicknames=
メソッドを定義してあります。
@user = User.create(name: '孫悟空')
@user.add_nickname('カカロット')
@user.nicknames
@user.nicknames = %w(カカロット 孫くん ゴクウ)
@user.nicknames
削除系
削除は、remove_nickname
メソッドと、remove_all_nicknames
メソッドを定義してあります。
@user = User.create(name: '孫悟空')
@user.nicknames = %w(カカロット 孫くん ゴクウ)
@user.remove_nickname('孫くん')
@user.nicknames
@user.remove_all_nicknames
@user.nicknames
検索系
検索系は、完全一致検索と、部分一致検索を定義してあります。本名(?)を検索対象にするためにオプションwith_name_column
があり、デフォルトでtrue
になっています。
もしニックネームのみを検索対象にしたい場合は、false
を設定します。
@user = User.create(name: '孫悟空')
@user.add_nickname('カカロット')
User.match_by_nickname('孫悟空').exists?
User.match_by_nickname('カカロット').exists?
User.match_by_nickname('悟空').exists?
User.partial_match_by_nickname('悟空').exists?
User.partial_match_by_nickname('カカ').exists?
User.match_by_nickname('孫悟空', with_name_column: false).exists?
User.match_by_nickname('カカロット', with_name_column: false).exists?
User.partial_match_by_nickname('悟空', with_name_column: false).exists?
User.partial_match_by_nickname('カカ', with_name_column: false).exists?
参照系
with_nicknames
スコープを定義しているので、これを呼ぶとeager_load
が実行されるのでN+1は起きません。
@user = User.with_nicknames.first
以上です。
こんな機能があったらいいなぁとか、IssueなりPRなりお願いします!