ruby-on-rails - FactoryGirl 通过调用另一个工厂的方法来定义属性

标签 ruby-on-rails ruby-on-rails-3 testing factory-bot

这是来自 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.iduser 不是 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/

相关文章:

javascript - 我在哪里可以学习如何在 Ruby on Rails 中制作 Javascript 支持的下拉菜单?

ruby-on-rails - PG undefinedtable 错误关系用户不存在

excel - 用于生成 excel ruby​​ 的 gem list pdfkit

ruby-on-rails - Rails 3.2 Engine 我如何在数据库中保存 session ?

testing - cypress 和 select2 未在选择时触发

ruby-on-rails - 具有多个应用程序的 SimpleCov - 或者简而言之,Simplecov 是如何工作的?

ruby-on-rails - 为什么我的 gem 'dotenv-rails' 变量没有加载?

javascript - 从下拉列表中的值获取id,将其发送到 Controller ,加载数据并重新加载页面

angular - 使用 TestBed 为具有依赖关系的 Angular 服务创建测试用例

testing - 如果您没有从 process.env 获得 url,如何取消测试执行