Rails の unit test を書いていて、関連がないテーブルの primary key が知りたい状況があった。
関連があるテーブルだと、
class User < ActiveRecord::Base
has_many :posts
end
class Post < ActiveRecord::Base
belongs_to :user
end
みたいなときに
test/fixtures/users.yml
chihaya:
name: 千早
test/fixtures/posts.yml
first:
user: chihaya
title: くっ…!
body: 先日フェスがあったのですが…
みたいな感じにすると関連が作れる。
今回は、単純なログみたいなもので、色んなテーブルの id を、target_id みたいなところにしまって、クラス名と合わせてユニークになるように管理してた。数が多かったのと関連付けて取る必要が無かったので、関連を作ってなかったんだけれども、fixture を書く時に、外部の id の取得方法に迷った。
つまり、先ほどの例で、has_many, belongs_to が無かった時にどうするかということです。
users.yml に、 id:1 とか書くというのも1つの方法です。
id を指定せずに rake fixtures:load ってすると、id が結構大きな数字になりますが、あれはラベルの文字列によって計算された値みたいですね。
ActiveRecord::Fixtures.identify(label) というメソッドで計算されていて、プラットフォーム依存で、同じ文字列を与えれば同じ値が返ってくる仕組みになっているようです。
そうすると、先ほどの例だと
test/fixtures/posts.yml
first:
user_id: <%= ActiveRecord::Fixtures.identify(:chihaya) %>
title: くっ…!
body: 先日フェスがあったのですが…
とすると、常に千早の id が取れるようになります。ActiveRecord::Fixtures.identify(:chihaya) の値は、見て分かるようにテーブルに依存することはなく、別テーブルで chihaya というラベルを使うと、同じ id になります。ActiveRecord::Fixtures が見つからないときは、 require 'active_record/fixtures' とします。
なんだろうなーと思ってた巨大な整数の id の計算方法がわかってすっきりしました。