factory_girlネタも今回で3回目。今回は関連について書いていきます。
関連データの記述方法
postsテーブルを次のように作成して、userへの参照を持たせるようにします。
class CreatePosts < ActiveRecord::Migration def change create_table :posts do |t| t.string :title t.text :body t.references :user t.timestamps end add_index :posts, :user_id end end
また、Postモデルにbelongs_toを書いておきます。
class Post < ActiveRecord::Base belongs_to :user end
これで準備OK。factoriesディレクトリの下にposts.rbを次のように記述します。
FactoryGirl.define do factory :post do title "MyString" body "MyText" user end end
userと書かれている行がpostデータとの関連が張っているところです。関連名=factory_girlの定義名の場合は、特に名前を指定せずとも適切な物(今回は、定義名userのもの)が指定されたことになります。
作成してみましょう。
irb(main):002:0> p = FactoryGirl.build(:post) (0.1ms) begin transaction SQL (0.7ms) INSERT INTO "users" ("created_at", "email", "name", "updated_at") VALUES (?, ?, ?, ?) [["created_at", Fri, 04 May 2012 07:59:47 UTC +00:00], ["email", "hoge@example.com"], ["name", "User1"], ["updated_at", Fri, 04 May 2012 07:59:47 UTC +00:00]] (3.6ms) commit transaction => #<Post id: nil, title: "MyString", body: "MyText", user_id: 8, created_at: nil, updated_at: nil> irb(main):003:0>
新しくUserが作成され、その作られたUserに対して関連を貼ったPostデータが作成されます。Userデータはテーブルに保存されますが、Postデータは(FactoryGirl.buildを使っているため)保存されません。
関連名≠factory_girlの定義名の場合は、association ... といったちょっと面倒くさいことを書く必要があります。
FactoryGirl.define do factory :post2, :class => Post do title "post2 sample title" body "post2 sample body" association :user, factory: :user4 end end
こう書いておいて、user4の定義は、
FactoryGirl.define do sequence(:sequence_string) { |n| "email#{n}@example.com" } factory :user4, :class => User do name { FactoryGirl.generate(:sequence_string) } email { "#{name}@exmaple.com" } end end
と書いておくと、
irb(main):001:0> p = FactoryGirl.build(:post2) (0.1ms) begin transaction SQL (47.6ms) INSERT INTO "users" ("created_at", "email", "name", "updated_at") VALUES (?, ?, ?, ?) [["created_at", Fri, 04 May 2012 08:17:39 UTC +00:00], ["email", "email1@example.com@exmaple.com"], ["name", "email1@example.com"], ["updated_at", Fri, 04 May 2012 08:17:39 UTC +00:00]] (3.5ms) commit transaction => #<Post id: nil, title: "post2 sample title", body: "post2 sample body", user_id: 9, created_at: nil, updated_at: nil> irb(main):002:0>
上の例のように、Userにはuser4で定義したデータで関連が貼られます。
まとめ
というわけで、まだまた機能はありますが、ひと通りの使い方は書けたかなと思います。
で、ここからはfactory_girlの使い方で気がついたプチノウハウなどを。
- データの定義についてはかなり便利。
- 一個一個のデータに名前をつけるのは結構だるい。権限ロールごとに10ユーザーを作るってことを考えると、1ユーザーごとに定義するのではなくて、権限ロールごとに作ったほうが良い。で、ユーザーをユニークにするのはsequenceなどを使う。
- いわゆるマスタデータ(都道府県一覧とか)をfactory_girlでつくろうとしない。factory_girlの処理もそれなりに時間がかかるので、seed.rbやFixtureで定義したほうが良いかと。
というわけで、3回にわたって書いてきましたfactory_girlの使い方、これにて終了。