我有以下问题。我有一个模型,其中有一个变量(金额)的验证,取决于另一个枚举变量(种类)的值。
class ScopeChange < ActiveRecord::Base
enum kind: [ :add, :remove, :change ]
validates :amount, :numericality => { :greater_than_or_equal_to => 1 } , if: "self.add?"
validates :amount, :numericality => { :less_than_or_equal_to => -1 } , if: "self.remove?"
end
我想创建一个构建它的工厂,我已经尝试将if语句放在变量的实际创建者中(它应该是一个if elsif else语句,这只是用于测试)
FactoryGirl.define do
factory :sprint_scope_change do
association :sprint
kind { Faker::Number.between(0,2) }
amount { kind == :add ? Faker::Number.between(-7,7) }
date { Faker::Date.between(sprint.start_date, sprint.end_date) }
description { Faker::Lorem.sentence }
end
end
哪个不起作用,它完全忽略了if语句,只是在-7和7之间创建了一个随机数。接下来我尝试在工厂外创建一个变量:sprint_scope_change并在其中:
FactoryGirl.define do
factory :sprint_scope_change do
sprint_scope_change.kind = Faker::Number.between(0,2)
sprint_scope_change.amount = if sprint_scope_change.kind == 0
Faker::Number.between(1,7)
elsif sprint_scope_change.kind == 1
Faker::Number.between(-7,-1)
else
Faker::Number.between(-7,7)
end
association :sprint
kind { kind }
amount { amount }
date { Faker::Date.between(sprint.start_date, sprint.end_date) }
description { Faker::Lorem.sentence }
end
end
在某种程度上起了作用,但每当我打电话给工厂时它都给出了完全相同的值。我尝试的最后一种方式是使用before(:create),但是现在程序只是爆炸并且“堆栈级别太深”,我试图重现一些我见过的例子但是肯定是错的:
FactoryGirl.define do
factory :sprint_scope_change do
before(:create) { |sprint_scope_change|
sprint_scope_change.kind = Faker::Number.between(0,2)
sprint_scope_change.amount = if sprint_scope_change.kind == 0
Faker::Number.between(1,7)
elsif sprint_scope_change.kind == 1
Faker::Number.between(-7,-1)
else
Faker::Number.between(-7,7)
end
}
association :sprint
kind { kind }
amount { amount }
date { Faker::Date.between(sprint.start_date, sprint.end_date) }
description { Faker::Lorem.sentence }
end
end
我可以做些什么来实现我的目标?到目前为止我尝试过的是什么问题?任何这些问题都很高兴知道。
(值得一提的是,我也是铁杆和红宝石的新手)
答案 0 :(得分:2)
你真的需要这种随机行为吗?你想要的是控制。我建议使用特征。
FactoryGirl.define do
factory :sprint_scope_change do
trait :add do
kind { 0 }
amount { random_valid_amount_for_add }
end
trait :remove do
kind { 1 }
amount { ... }
end
end
end
FactoryGirl.create :sprint_scope_change, :add
如果你想要随机性,那么你就是谁掌控了
let(:random_scope_changes) {
3.times.map do |i|
case rand(2)
when 0 then FactoryGirl.create(:sprint_scope_change, :add)
when 1 then FactoryGirl.create(:sprint_scope_change, :remove)
# etc.
end
end
}
答案 1 :(得分:1)
很确定你只需要一个块:
sprint_scope_change.amount do
if kind == 0
Faker::Number.between(1,7)
elsif kind == 1
Faker::Number.between(-7,-1)
else
Faker::Number.between(-7,7)
end
end