【发布时间】:2014-01-21 10:18:44
【问题描述】:
我是 FactoryGirl 的新手,在 Ruby 中,我正在尝试编写一些 rspec,但在循环依赖方面遇到了一些麻烦。我搜索并尝试了几件事,最后一个生成了无限循环,我不得不关闭我的 WM。 (触发 100%)
模特/投票
class Vote < ActiveRecord::Base
has_many :vote_options
models/vote_option
class VoteOption < ActiveRecord::Base
belongs_to :vote
accepts_nested_attributes_for :vote_options, reject_if: :all_blank
spec/models/vote_spec
describe Vote do
describe 'should return the good label' do
let(:nobody) { FactoryGirl.create(:vote, visibility: 0) }
it "should not be visible" do
nobody.intercom_custom_data[:visibility].should == I18n.t("votes.new.visibility_none")
end
end
end
规格/工厂
factory :vote do
team
question 'Question?'
question_type 0
# Avoid validation because of the circular dependency.
# https://stackoverflow.com/questions/9322353/factory-girl-create-that-bypasses-my-model-validation
after(:build) do |vote|
vote.vote_options << VoteOption.create(vote_id: vote.id)
#vote.save!(:validate => false)
end
end
factory :vote_allowed do
user
vote
allowed 1
end
factory :vote_casted do
vote_allowed
vote_options
end
factory :vote_options do
vote
title 'default option'
end
这是执行无限循环的代码。我猜是因为循环依赖,它无限地创建了 vote 和 vote_options。
所以,我得到了一个有很多 vote_options(用户选择)的投票,每个 vote_options 都包含它的父 ID。如果字段为空白,验证会拒绝创建,我们在保存新的 vote/vote_options 的代码方面没有问题,因为一切都在同一个事务中完成。
但是,使用 rspec,我不能同时创建相互依赖的投票和投票选项行。 (或者我不知道该怎么做)
所以,我试图避免这样的验证:
after(:create) do |vote|
VoteOption.create(vote_id: vote.id)
vote.save!(:validate => false)
end
但我得到了一个错误:
Failure/Error: let(:nobody) { FactoryGirl.create(:vote, visibility: 0) }
ActiveRecord::RecordInvalid:
Validation failed: Vote options can't be blank
我之前尝试使用after_create 而不是after(:create),但我的FactoryGirl 是4.3,所以after_create 不再存在。我在https://stackoverflow.com/questions/15003968/undefined-method-after-create-with-factorygirl 找到了一个关于“如何在 >3.3 中使用 after_create”的教程,但它对我不起作用,我不应该得到“投票选项不能为空”......所以我看了一下在上一个链接中链接的文档,我尝试在 spec/factories
FactoryGirl.define do
after(:create) {|instance| instance.create }
但我真的不明白我应该做什么,也不明白问题出在哪里。有什么想法吗?
编辑#1:
factory :vote do
team
question 'Question?'
question_type 0
association :vote_options, factory: :vote_options
# tried with :create and :build
after(:create) do |vote, evaluator|
create_list(:vote_options, 1, vote: vote)
end
end
【问题讨论】:
-
触发此问题的规格是什么样的?
-
我不确定是否清楚地理解了这个问题。我在其他规格上没有问题。这里的问题是因为模型的设计方式,具有循环依赖关系,并且如果字段为空白,验证拒绝创建新实例,所以我需要避免验证。我用
vote.save!(:validate => false)完成了它,它似乎有效,因为我没有得到空白字段”但我得到了“after_create is not function”,所以我使用了“after(:create)”但我又得到了“空白字段”,所以我不知道什么在这里不起作用。 -
你为什么不使用 factorygirl 关联?
-
@majioa 你是什么意思?正如我所说,我是 FactoryGirl/Ruby 的新手,我在一个现有的大型项目上工作,我正在尝试弄清楚很多事情,我对 FactoryGirl 中的关联一无所知。
标签: ruby-on-rails ruby validation rspec