这是来自 FactoryGirl 的示例 documentation :
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 时对规范本身进行了一些重构.创建
。
上面的代码结合了 mguymon 的建议。谢谢!
最终更新
回去重读后Hartl's discussion on model associations ,我才得以不了了之。我上面的内容在技术上是有效的,但当我在我的规范中构建或创建作业时实际上并没有正确传递属性。这是我应该拥有的:
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
block 。
顺便说一句,我还了解到我可以通过在 expect
语句中包含 puts @job
进行调试,或者调用 @job.assignee_id
以确保正确加载属性。当该特定规范运行时,puts
语句将直接从规范中的 F
或 .
输出。
最佳答案
对于最新版本的FactoryGirl,使用association
映射到其他ActiveRecord Models:
factory :job do
# ...
association :assignee, factory: :user
end
这直接来自 the docs .
从您发布的错误来看,它表明您正在尝试获取 user.id
但 user
不是 ActiveRecord 实例,而是来自 FactoryGirl 的代理。如果您使用 association
方法,则不会出现此错误。如果您需要直接访问模型,则必须先手动构建它。您可以通过在您的工厂中传递一个 block 来做到这一点:
factory :job do
assignee_id { FactoryGirl.create(:user).id }
end
看起来您正在尝试关联同一个模型两次,为此您可以使用 before_create
回调来创建一个 User 模型并分配给 user
和 受让人
:
factory :job do
before(:create) do |job|
user = FactoryGirl.create(:user)
job.assignee = user
job.user = user
end
end
关于ruby-on-rails - FactoryGirl 通过调用另一个工厂的方法来定义属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15999675/