在 FactoryGirl 中使一个变量依赖于另一个变量的值
Making a variable depend on the value of another in FactoryGirl
我有以下问题。我有一个模型,其中根据另一个枚举变量(种类)的值验证变量(数量)。
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),但现在程序爆炸了,"stack level is too deep",我试图重现一些我见过的例子,但肯定有问题:
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
我可以做些什么来实现我想做的事情?到目前为止我尝试过的有什么问题?很高兴知道这些问题中的任何一个。
(值得一提的是我也是rails和ruby的新手)
很确定你只需要一个块:
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
你真的需要这种随机行为吗?您在规格中想要的是控制。我建议使用特征。
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
}
我有以下问题。我有一个模型,其中根据另一个枚举变量(种类)的值验证变量(数量)。
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),但现在程序爆炸了,"stack level is too deep",我试图重现一些我见过的例子,但肯定有问题:
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
我可以做些什么来实现我想做的事情?到目前为止我尝试过的有什么问题?很高兴知道这些问题中的任何一个。
(值得一提的是我也是rails和ruby的新手)
很确定你只需要一个块:
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
你真的需要这种随机行为吗?您在规格中想要的是控制。我建议使用特征。
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
}