Rubyのテストデータ作成gem

少し古い WebDB Press(vol.85)のRubyの記事(Railsらくらくテストデータ準備)を見ていたら
fakerの紹介がされていました。
 
ちゃんと使ったことなかったので今更ながら触ってみました。
記事中はおそらくtypoでffakerとなってしまっていたと思われるので、ついでにffaker - Rubyも見てみました。

結論から

faker/ffakerどちらもとても良いですが、日本語の名前(仮名)と住所については対応できていません。
そんな不満を解消するのがgimeiでした。
faker/ffaker + gimei で幸せになれそうです。
 

Faker

stympy/faker
railsでfakerを使用するには、以下のように環境ごとにスクリプトを書いて
db/fixtures/development
あとは、rake db:seed_fu すればok。
 
seed.rbは使っていたのですが、何度実行されても良いようにするために
データのクリアなどを考慮する必要がありましたが、
faker/ffakerは制約の指定ができ、データが存在すれば突っ込まないようにすることが容易にできます。

簡単な使い方

# db/fixtures/development/users.rb

User.seed(:name) do |seed|
  seed.name = 'qiitan'
  seed.email = 'quiitan@example.com'
end

# 複数書けるよ
User.seed(:name,
  { name: 'quiitan', email: 'qiitan@example.com' },
  { name: 'kobito', email: 'kobito@example.com' }
)

日本語の扱い

localeの指定方法が用意されていますが、emailと組み合わせると
微妙な動きになるようで、回避方法としてi18n を指定すると
今の所期待する動作になりました。

require 'i18n'
I18n.locale = :ja
# Faker::Config.locale = :ja  # これではemailがおかしくなる
10.times do
  User.seed(:email) do |s|
    s.first_name = Faker::Name.first_name
    s.last_name = Faker::Name.last_name
    s.email = Faker::Internet.email
    s.description = Faker::Lorem.sentence
  end
end
== Seed from /private/tmp/seedfu/db/fixtures/development/users.rb
 - User {:first_name=>"美桜", :last_name=>"高橋", :email=>"dominique.konopelski@considine.name", :description=>"Deserunt consequatur eaque provident adipisci."}
 - User {:first_name=>"健", :last_name=>"柴田", :email=>"eveline@wilderman.net", :description=>"Sunt facere error quod modi quam aut deleniti sit."}
 - User {:first_name=>"大和", :last_name=>"藤本", :email=>"oral@bradtke.net", :description=>"Voluptas quidem ad quo aut amet non velit."}
 - User {:first_name=>"太郎", :last_name=>"太田", :email=>"arnaldo@moen.org", :description=>"Dolorum aut corrupti omnis ut veniam."}
 - User {:first_name=>"響", :last_name=>"上野", :email=>"candelario_pouros@marks.com", :description=>"Ut quam aut harum non maiores adipisci."}
 - User {:first_name=>"大和", :last_name=>"杉山", :email=>"roberta.quitzon@ko.com", :description=>"Magnam necessitatibus natus odit."}
 - User {:first_name=>"莉子", :last_name=>"原田", :email=>"murl@wolf.info", :description=>"Et dolor id dolore assumenda."}
 - User {:first_name=>"優奈", :last_name=>"今井", :email=>"willow@hoppe.biz", :description=>"Quas dolor unde maxime rerum."}
 - User {:first_name=>"奈々", :last_name=>"後藤", :email=>"carroll@rogahn.biz", :description=>"Itaque debitis aut fugiat."}
 - User {:first_name=>"愛子", :last_name=>"藤井", :email=>"westley@rowekreiger.biz", :description=>"Tempore veritatis reprehenderit libero molestias rem voluptas."}
>> Faker::Address.street_name
=> "工藤Square"

住所はちょっと微妙です。

ffaker

ffaker/ffaker - Ruby
fakerのforkらしく早く動作するそうです。interfaceもほぼ同じですが
localeの設定が異なります。module名にlocaleが含まれています。
どの項目が対応しているかはreferenceを見ればわかりますが、
日本語は「JobJA(職業)」と「NameJA(名前)」しかありません。
fakerに職業は用意されていないので、使うメリットはありそうな気もしますが
職業でランダムデータ欲しいという要件は少なさそうです。
ffaker/REFERENCE.md at master · ffaker/ffaker

10.times do
  User.seed(:email) do |s|
    s.first_name = FFaker::NameJA.first_name
    s.last_name = FFaker::NameJA.last_name
    s.email = FFaker::Internet.email
    s.description = FFaker::Lorem.sentence
  end
end
== Seed from /private/tmp/seedfu/db/fixtures/development/users.rb
 - User {:first_name=>"達也", :last_name=>"川田", :email=>"trisha@kreiger.name", :description=>"Non cum omnis autem iste atque."}
 - User {:first_name=>"円", :last_name=>"坂口", :email=>"seth@barrows.com", :description=>"Suscipit nulla deserunt molestiae facere voluptatem."}
 - User {:first_name=>"汐", :last_name=>"田場", :email=>"isobel@west.info", :description=>"Sed voluptatibus dolorum illum quo repudiandae velit."}
 - User {:first_name=>"栄", :last_name=>"野呂", :email=>"soledad_herzog@turcotte.co.uk", :description=>"Numquam unde debitis sed aliquam ipsum in et itaque."}
 - User {:first_name=>"ゆたか", :last_name=>"川路", :email=>"adelbert@schowalter.co.uk", :description=>"Facilis sunt accusantium non commodi quisquam delectus."}
 - User {:first_name=>"恵美", :last_name=>"佐久間", :email=>"evelyn@halvorson.co.uk", :description=>"Modi qui quae excepturi quod."}
 - User {:first_name=>"七海", :last_name=>"坂東", :email=>"taurean@kris.com", :description=>"Rem iure neque excepturi dolor."}
 - User {:first_name=>"律子", :last_name=>"天久", :email=>"brant@hand.co.uk", :description=>"Error rerum ut sunt nostrum voluptatum non quaerat est."}
 - User {:first_name=>"太陽", :last_name=>"福田", :email=>"rae@morissette.name", :description=>"Saepe earum sit molestias architecto ad."}
 - User {:first_name=>"大樹", :last_name=>"堀内", :email=>"osvaldo_breitenberg@dubuquejacobs.com", :description=>"Voluptatibus aut odio pariatur quis alias qui velit."}

gimei

gimei
faker/ffaker は素晴らしいのですが、なんといっても名前の仮名が扱えないのが残念です。
それを解消してくれるのがgimeiです。

# 名前はgimeiを利用する
10.times do
  User.seed(:email) do |s|
    g = Gimei.name
    s.first_name = g.first.kanji
    s.last_name  = g.last.kanji
    s.first_name_kana = g.first.hiragana
    s.last_name_kana  = g.last.hiragana

    s.email = Faker::Internet.email
  end
end
 == Seed from /private/tmp/seedfu/db/fixtures/development/users.rb
 - User {:first_name=>"莉麻", :last_name=>"笠原", :first_name_kana=>"りお", :last_name_kana=>"かさはら", :email=>"beau.schneider@kautzerluettgen.co"}
 - User {:first_name=>"賢吾", :last_name=>"吉岡", :first_name_kana=>"けんご", :last_name_kana=>"よしおか", :email=>"daisha@bergeoconnell.org"}
 - User {:first_name=>"槇絵", :last_name=>"金子", :first_name_kana=>"まきえ", :last_name_kana=>"かねこ", :email=>"cleta@mcdermotthilpert.io"}
 - User {:first_name=>"国嘉", :last_name=>"黒田", :first_name_kana=>"くによし", :last_name_kana=>"くろだ", :email=>"breana.senger@moorecain.org"}
 - User {:first_name=>"朝栄", :last_name=>"大森", :first_name_kana=>"ともえ", :last_name_kana=>"おおもり", :email=>"abbigail@purdy.net"}
 - User {:first_name=>"真実", :last_name=>"横山", :first_name_kana=>"まなみ", :last_name_kana=>"よこやま", :email=>"leonard@mertzmcclure.co"}
 - User {:first_name=>"孝弘", :last_name=>"服部", :first_name_kana=>"たかひろ", :last_name_kana=>"はっとり", :email=>"caria@kozey.info"}
 - User {:first_name=>"華玲", :last_name=>"西田", :first_name_kana=>"かれい", :last_name_kana=>"にしだ", :email=>"chanelle_sanford@lang.biz"}
 - User {:first_name=>"蒔", :last_name=>"松原", :first_name_kana=>"まき", :last_name_kana=>"まつばら", :email=>"ricky@feeneyharber.info"}
 - User {:first_name=>"翼沙", :last_name=>"木村", :first_name_kana=>"つばさ", :last_name_kana=>"きむら", :email=>"natasha_mitchell@hauck.co"}

最高ですね。
まぁ、ここまでは知っていたのですが、なんと住所にも対応していました。
住所をランダムで返す

address = Gimei.address
pp address
#<Gimei::Address:0x007fa34390f040
 @city=
  #<Gimei::Address::City:0x007fa34390eff0 @cities=["米子市", "よなごし", "ヨナゴシ"]>,
 @prefecture=
  #<Gimei::Address::Prefecture:0x007fa34390f018
   @prefectures=["大阪府", "おおさかふ", "オオサカフ"]>,
 @town=
  #<Gimei::Address::Town:0x007fa34390efc8 @towns=["童仙房", "どうせんぼう", "ドウセンボウ"]>>