2016-10-19 2 views
1

J'essaye de créer des données factices avec FactoryGirl.Quadruple éléments enfants imbriqués dans FactoryGirl

L'utilisateur a beaucoup de publications, l'article a beaucoup de vidéos, la vidéo a beaucoup de commentaires. Les commentaires appartiennent à la vidéo et à l'utilisateur. La vidéo appartient à la publication et à l'utilisateur. Le message appartient à l'utilisateur.

Je voudrais créer au moins 20 utilisateurs, chacun avec au moins 10 messages, chaque poste avec au moins 1 vidéo, chaque vidéo avec au moins 1 commentaire.

Jusqu'à présent, j'ai les usines suivantes mais je n'arrive pas à faire fonctionner les vidéos ou les commentaires.

spec/usines/comments.rb

spec/usines/posts.rb

FactoryGirl.define do 
    factory :post do 
    sequence(:title) { |n| "#{n}title" } 
    date Date.today.strftime('%m/%d/%Y') 
    body Faker::Lorem.paragraph(3) 
    tags Faker::Lorem.words(4) 
    user 

    trait :with_videos do 
     after(:build) do |post| 
     create(:video, post: post) 
     end 
    end 
    end 
end 

spec/usines/users.rb

FactoryGirl.define do 
    factory :user do 
    first_name Faker::Name.first_name 
    last_name Faker::Name.last_name 
    sequence(:username) { |n| "#{n}username" } 
    sequence(:email) { |n| "#{n}[email protected]" } 
    phone Faker::PhoneNumber.phone_number 
    password Faker::Internet.password(6, 20) 
    country Faker::Address.country 
    state Faker::Address.state_abbr 
    city Faker::Address.city 
    zip Faker::Address.zip 
    seeking_coach true 
    accept_email true 
    accept_phone true 
    end 
end 

spec/usines/videos.rb

FactoryGirl.define do 
    factory :video do 
    sequence(:title) { |n| "#{n}title" } 
    sequence(:url) { |n| "https://www.youtube.com/watch?v=tYm_#{n}2oCVdSM" } 
    embed_id { "#{url}.split('=').last" } 
    post 
    user 

    trait :with_comments do 
     after(:build) do |video| 
     create(:comment, video: video) 
     end 
    end 
    end 
end 

Répondre

0

Je pense que dans les usines crochet devrait être after(:create) au lieu de after(:build), par exemple:

after(:create) do |video| 
    create(:comment, video: video) 
end 

Voici toutes les usines mises à jour:

spec/usines/users.rb

FactoryGirl.define do 
    factory :user do 
    first_name Faker::Name.first_name 
    last_name Faker::Name.last_name 
    sequence(:username) { |n| "#{n}username" } 
    sequence(:email) { |n| "#{n}[email protected]" } 
    phone Faker::PhoneNumber.phone_number 
    password Faker::Internet.password(6, 20) 
    country Faker::Address.country 
    state Faker::Address.state_abbr 
    city Faker::Address.city 
    zip Faker::Address.zip 
    seeking_coach true 
    accept_email true 
    accept_phone true 

    trait :with_10_posts do 
     after(:create) do |user| 
     create_list(:post, 10, :with_videos, user: user) 
     end 
    end 
    end 
end 

spec/factories/posts.rb

FactoryGirl.define do 
    factory :post do 
    sequence(:title) { |n| "#{n}title" } 
    date Date.today.strftime('%m/%d/%Y') 
    body Faker::Lorem.paragraph(3) 
    tags Faker::Lorem.words(4) 
    user 

    trait :with_videos do 
     after(:create) do |post| 
     create(:video, :with_comments, post: post) 
     end 
    end 
    end 
end 

spec/usines/videos.rb

FactoryGirl.define do 
    factory :video do 
    sequence(:title) { |n| "#{n}title" } 
    sequence(:url) { |n| "https://www.youtube.com/watch?v=tYm_#{n}2oCVdSM" } 
    post 

    trait :with_comments do 
     after(:create) do |video| 
     create(:comment, video: video) 
     end 
    end 
    end 
end 

spec/usines/comments.rb

FactoryGirl.define do 
    factory :comment do 
    sequence(:body) { |n| "#{n}body" } 
    video 
    end 
end 

et de test RSpec pour assurer que l'installation des usines fonctionne:

describe 'Factories' do 
    it 'creates 20 users, each with at least 10 posts, each post with at least 1 video, each video with at least 1 comment' do 
    FactoryGirl.create_list(:user, 20, :with_10_posts) 
    expect(User.count).to eq(20) 
    user = User.take 
    expect(user.posts.count).to be >= 10 
    post = user.posts.take 
    expect(post.videos.count).to be >= 1 
    video = post.videos.take 
    expect(video.comments.count).to be >= 1 
    end 
end 

Voici tout le code - https://github.com/shhavel/stackoverflow_question_40136020