Factory Girl - 如何为具有关联的模型创建工厂?

时间:2014-01-09 22:33:42

标签: ruby-on-rails ruby ruby-on-rails-4 factory-bot

我正在尝试为我的用户模型创建一个工厂及其关联。但是,我似乎无法在我的Factory Girl代码中获得正确的语法。我已经阅读了Factory Girl文档,但似乎无法找到任何有关我的具体用例的帮助。我运行测试套件时目前收到的错误是:

undefined method `subscription_args' for #<FactoryGirl::SyntaxRunner...

Trait not registered: valid_card_data

以下是我的模特和协会:

User.rb

has_one :subscription
has_one :plan, :through => :subscription
has_many :projects

Project.rb

belongs_to :user

Plan.rb

has_many :subscriptions

Subscription.rb

belongs_to :plan
belongs_to :user

这是我的工厂女孩​​代码:

FactoryGirl.define do

  factory :user do
    first_name "Joel"
    last_name "Brewer"
    email { "#{first_name}.#{last_name}@example.com".downcase }
    password "foobar"
    password_confirmation "foobar"
    user_type "entrepreneur"

    subscription { build(:subscription, subscription_args) }

    after(:create) do |user|
      user.subscription.save!
    end
  end

  factory :subscription do
    user
    plan_id '4'

    ## I am trying to access a helper method from support/utilities ##
    ## This call to valid_card_data doesn't seem to be working...   ##

    stripe_card_token valid_card_data 
    email "joel.brewer@example.com"
  end

  factory :project do
    title "Sample Project"
    user
  end
end

2 个答案:

答案 0 :(得分:2)

以下是我过去的表现。当然不是唯一的方式:

(注意我正在使用黄瓜。)

require 'factory_girl'

FactoryGirl.define do

  factory :user do |f|
    f.username 'superman'
  end

  factory :message do |f|
    f.association :user
    f.content 'Test message content'
  end

end

这确定了消息工厂应该将消息与用户相关联。哪个用户?我在使用时确定了这一点:

steps.rb:

Given(/^there is a user$/) do
  @user = FactoryGirl.create(:user)
end

Given(/^the user has posted the message "(.*?)"$/) do |message_text|
  FactoryGirl.create(:message, :content => message_text, :user => @user)
end

When(/^I visit the page for the user$/) do
  visit user_path(@user)
end

Then(/^I should see "(.*?)"$/) do |text|
  page.should have_content(text)
end

我的方法,在使用点指定对用例有意义。例如给定是用户(必须首先建立用户)并且该用户已发布消息(现在可以建立现有用户与消息之间的关系)......

这可能会或可能不会对你有好处,但这就是我如何做到的。这可能对你有帮助,也可能没有帮助,但希望如此。

答案 1 :(得分:1)

有几种方法可以做到这一点。这是一个例子:

after(:build) do |keyword, evaluator|
  keyword.text = FactoryGirl.build(:keyword_text, :value => evaluator.keyword_text)
end

您不需要subscription_args - 这些可以在您致电工厂时设置。

你在哪里定义你的特质?

在我的工厂里,他们看起来像这样:

trait :with_category_associations do
  ..

对于您可能想要使用的更复杂的关系:

  after(:create) do |keyword, evaluator|
    evaluator.categories.each do |category|
      FactoryGirl.create(:join_inventory_keyword, final: keyword, category: category)
    end
  end