LoginSignup
10
12

More than 5 years have passed since last update.

1対多のモデルに対するFactoryGirl

Last updated at Posted at 2015-02-05

Railsつかってるけど、知らないことが多くて各駅停車で開発してるような気分だったのですがちょっとづつ慣れてきて、各駅停車状態からちょっとづつ脱しつつあります。

最近はTDD/BDDな感じで作業してるのですがModelのspecを書く時にFactoryGirlの使い方で一部わからなかったことがあって今後また同じことでハマりそうなのでメモっておきます

環境は

  • rails 4.2.0
  • factory_girl 4.5.0
  • factory_girl_rails 4.5.0
  • rspec 3.1.0

という感じです

例えば、

  • レストラン
  • そのレストランに対する口コミ

という感じのモデルを定義したいとします。

generatorで以下のようにモデルを作成

./bin/rails g model restaurant name:string address:string
./bin/rails g model restaurant_review description:text restaurant:references

Restaurantモデルはこんな感じ

restaurant.reviewsで利用できるようにしたいのでclass_nameを利用してみました(これも知らなかった・・)

class Restaurant < ActiveRecord::Base
  has_many :reviews, class_name: RestaurantReview.name
end

口コミ情報に対応するモデルはこんな感じ

class RestaurantReview < ActiveRecord::Base
  belongs_to :restaurant
end

FactoryGirlの設定を行う

それぞれのモデルに対するFactoryGirlの設定を行います

口コミ情報に対応するRestaurantReviewモデルに対応するFactoryGirlの設定

こちらはそれほど苦労すること無く出来ました。

※sequenceの使い方もよくわかってなかったのですが、Qiitaのこちらの記事を見て改めて理解したのですが、連番で重複しないデータを定義出来るんですね。これは便利!

FactoryGirl.define do
  factory :restaurant_review do
    sequence(:description) { |n| "restaurant_review_description#{n}"}
  end
end

Restaurantモデルに対応するFactoryGirlの設定

で、本題に書いた1対多のモデルに対するFactoryGirlですがこれがわからなかったのですがreviewsに対して以下のようにブロックを渡しつつ、build_listというのを利用することで定義できるんですね

FactoryGirl.define do
  factory :restaurant do
    sequence(:name) { |n|  "restaurant_name#{n}" }
    sequence (:address) { |n| "restaurant_address#{n}" }
    reviews { build_list :restaurant_review, 1 }
  end
end

終わりに

Rails知らないことが多いけど、その分成長が感じられて面白い

10
12
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
12