質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
RSpec

RSpecはRuby用のBDD(behaviour-driven development)フレームワークです。

Q&A

解決済

1回答

1813閲覧

FactoryGirl で << という記法と、それに代入しているものがわかりません

bouyomisan

総合スコア87

RSpec

RSpecはRuby用のBDD(behaviour-driven development)フレームワークです。

0グッド

0クリップ

投稿2017/05/12 00:58

Contact と Phone というモデルに対して FactoryGirl でテスト用データを作っています。 contact.rb(1番目のコード)の afterコールバックの箇所がわかりません。

ruby

1after(:build) do |contact| 2 [:home_phone, :work_phone, :mobile_phone].each do |phone| 3 contact.phones << FactoryGirl.build(:phone, 4 phone_type: phone, contact: contact) 5 end 6end

ここが問題の箇所なのですが、

①contact.phones << の << とは、contact.phones という配列に FactoryGirl で作ったハッシュデータを代入しているということですか?これって別に配列じゃないと思うのですが、どうなのでしょう。

contact.phones << (略) contact: contact について、なぜ phone に contact の値をいれることができるのですか? contact の情報はすでに入っているとおもうのですが。

よろしくおねがいします。

ruby

1# spec/factories/contact.rb 2 3 FactoryGirl.define do 4 factory :contact do 5 firstname { Faker::Name.first_name } 6 lastname { Faker::Name.last_name } 7 email { Faker::Internet.email } 8 9 after(:build) do |contact| 10 [:home_phone, :work_phone, :mobile_phone].each do |phone| 11 contact.phones << FactoryGirl.build(:phone, 12 phone_type: phone, contact: contact) 13 end 14 end 15 end 16end

ruby

1#spec/factories/phone.rb 2 3FactoryGirl.define do 4 factory :phone do 5 association :contact 6 phone "111-222-333" 7 8 factory :home_phone do 9 phone_type "home" 10 end 11 factory :work_phone do 12 phone_type "work" 13 end 14 factory :mobile_phone do 15 phone_type "mobile" 16 end 17 end 18end 19コード

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

こんにちは。
最近使っているので回答を書いてみますね。間違った点があればご指摘いただけると幸いです。

Contact と Phoneのモデルのソースも載せていただけるといいかなと思いますが...。

Contact(連絡先となる人物) 1人に対して、Phone(電話)が複数という関係なのですよね。

contact.phones << の << とは、contact.phones という配列に FactoryGirl で作ったハッシュデータを代入しているということですか?これって別に配列じゃないと思うのですが、どうなのでしょう。

FactoryGirlでContactのインスタンスを作る際、buildのタイミングで、一緒にPhoneのインスタンスをbuildして、contact と phoneを関連付けしています。

たとえばrails consoleで定義したFactoryを使ってContactのインスタンスを作ってみると、一緒に関連するPhoneも出来ていると思います

contact = FactoryGirl.build(:contact) puts contact puts contact.phones puts contact.phones.length # たぶん3件 puts contact.phones.first # たぶん typeがhome_phone

contact.phones << (略) contact: contact について、なぜ phone に contact の値をいれることができるのですか? contact の情報はすでに入っているとおもうのですが。

まず、FactoryGirl.build(:contact) を実行すると、基本の処理が終わったあとに after(:build) の箇所に処理が移ります。

このコールバック処理の中で、3種類のタイプの電話のインスタンスをFactoryGirl.build(:phone...)で作っています。
作ると同時に、phoneのインスタンス側から、親になるcontactへ関連付けしています。

contact の情報はすでに入っているとおもうのですが。

という点ですが、contact自身ではなくて、同時に生成するPhoneクラスのインスタンスに対しての設定になっています。
計3つのPhoneクラスのインスタンスそれぞれに、同じ連絡先となるcontactを関連づけています。
この段階で、phone -> contactの関連付けができます。

そのうえで、contact.phones << phone としてあげているので、こんどは contactからphoneへの関連付けができて、contact.phones で持っている電話を抽出することができるようになります。

# FactoryGirl.build(:contact) が実行されてインスタンスを生成すると、 # そのコールバックとして 作られたcontact インスタンスを引数にして、build後に処理したい # 内容を実行 after(:build) do |contact| # 3種類のタイプの電話のインスタンスをFactoryGirl.build(:phone...)で作って、 # contact のインスタンスに関連付けしている [:home_phone, :work_phone, :mobile_phone].each do |phone| contact.phones << FactoryGirl.build(:phone, phone_type: phone, contact: contact) end end

Contact用のFactoryGirlの中で一気に関連するPhoneも作っていますが、コールバック部分をコメントアウトして、以下のように使うのもありです。

# Rails consoleで試してみる場合 contact = FactoryGirl.build(:contact) puts contact.phones # この時点では無し [:home_phone, :work_phone, :mobile_phone].each do |phone| contact.phones << FactoryGirl.build(:phone, phone_type: phone, contact: contact) end puts contact.phones # 関連付けできている puts contact.phones.length # たぶん3件 puts contact.phones.first # たぶん typeがhome_phone

投稿2017/05/16 13:43

suama

総合スコア1997

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問