11

这是 FactoryGirl文档中的一个示例:

FactoryGirl.define do
  factory :post do
    name "Post name"
    user
  end
end

在此示例中,user正在调用另一个工厂。我想做的是有效地调用user.id,但将其设置为属性的定义。这是一个精简的示例:

**models/job.rb**
  ...
  belongs_to :assignee, :class_name => "User"
  belongs_to :user
  ...
  attr_accessible :assignee_id, :user_id
  ...
end


**factories/jobs.rb**
FactoryGirl.define do
  factory :job do
    assignee_id user.id      #what I would like to do, but triggers "undefined method 'id'" error
    user_id user.id          #user_id is an attribute of the model and is the job assignor
 end

我试图合并讨论别名的文档部分,但没有运气:

FactoryGirl.define do
  factory :user, :aliases => [:assignee] do
  ....

我觉得(希望?)我在这里很近,但任何见解都值得赞赏。谢谢。

编辑:这段代码让我的规范运行!

**factories/jobs.rb**

FactoryGirl.define do
  factory :job do
    before(:create) do |job|
      user = FactoryGirl.create(:user)
      job.assignee = user
      job.user  = user
    end

  association :assignee, factory: :user
  association :user, factory: :user
  sequence(:user_id) { |n| n }
  sequence(:assignee_id) { |n| n }
  ...
end

它通过了我的it { should be_valid }规范,所以看起来工厂很好,尽管我认为我在调用时对规范本身进行了一些重构FactoryGirl.create

上面的代码结合了 mguymon 的建议。谢谢!

最后更新

在回去重新阅读了Hartl 关于模型关联的讨论之后,我能够把这件事搁置一旁。我上面的内容在技术上是有效的,但是当我在我的规范中构建或创建工作时,实际上并没有正确传递属性。这是我应该拥有的:

FactoryGirl.define do
  factory :job do
    association :assignee, factory: :user
    user
  end
end

我的问题还源于我如何在规范中创建工厂,所以我应该这样做(但不是......叹气):

    let(:user) { create(:user) }
    before { @job = create(:job, user: @user) }

似乎我不需要association :user在我的工厂中明确地拥有,也不需要before上面的块。

顺便说一句,我还了解到我可以通过包含puts @jobexpect语句中进行调试,或者调用@job.assignee_id以确保属性被正确加载。当该特定规范运行时,该puts语句将由规范输出F.从规范输出。

4

1 回答 1

17

对于最新版本的 FactoryGirl,用于association映射到其他 ActiveRecord 模型:

factory :job do
  # ...
  association :assignee, factory: :user
end

这直接来自文档


从您发布的错误中,它表明您正在尝试获取user.iduser不是 ActiveRecord 实例,而是来自 FactoryGirl 的代理。如果您使用该association方法,您将不会收到此错误。如果您需要直接访问模型,则必须先手动构建它。您可以通过在工厂中传递一个块来做到这一点:

factory :job do
    assignee_id { FactoryGirl.create(:user).id }
end

看起来您正在尝试将同一模型关联两次,为此您可以使用before_create回调来创建 User 模型并分配给userand assignee

factory :job do

  before(:create) do |job|
      user = FactoryGirl.create(:user)
      job.assignee = user
      job.user = user
  end
end
于 2013-04-14T13:42:35.010 回答