我的国家工厂看起来像这样
FactoryGirl.define do
factory :country do
name { "Country_Name_#{rand(10000).to_s}#{('a'..'z').to_a.shuffle.join.first(10)}" }
alpha { ('a'..'z').to_a.shuffle.join.first(2) }
end
end
alpha是一个2字母的国家/地区代码,我为此验证了唯一性。
validates :alpha,
presence: true,
uniqueness:true,
length: {is: 2}
运行大型测试时,我经常遇到
ActiveRecord::RecordInvalid:
Validation failed: Alpha has already been taken
特别是在创建子记录时
factory :state do
name { "State_Name_#{rand(10000).to_s}#{('a'..'z').to_a.shuffle.join.first(10)}" }
country
end
有没有更好的方法来建造我的国家工厂以避免重复?或者是否有更好的方法来构建州工厂,以便belongs_to国家是新记录和现有记录的混合
对于其他来这里有类似问题的人来说,序列肯定是要走的路(感谢born4new和Slicedpan)。
在实现这一点时,我意识到我还有其他一些导致问题的问题。
首先,Database Cleaner未正确运行,因此数据库未在测试之间重置为干净状态。因此,我很快就遇到了重复。
我还发现每次测试后我都需要重置FactoryGirl序列。否则,对于长序列,我看到zx, zy, zz, a, b
,并且单个字符未通过我的验证。
#spec/rails_helper.rb
config.append_after(:each) do
DatabaseCleaner.clean
FactoryGirl.reload
end
答案 0 :(得分:2)
当事情必须是独特的时候,我倾向于使用序列。对于国家/地区代码,您需要枚举可能的国家/地区代码。一种方法是
sequence :country_code do |n|
i1 = n % 26
i2 = n / 26
chars = ('a'..'z').to_a
"#{chars[i1]}#{chars[i2]}"
end
然后在你的工厂你可以做到
factory :country do
name { "Country_Name_#{rand(10000).to_s}#{('a'..'z').to_a.shuffle.join.first(10)}" }
alpha { generate :country_code }
end
答案 1 :(得分:2)
运行大型测试时,
你最多(可能会少一些)26^2 = 676
可能的alpha组合,所以如果large tests
意味着更多,那么就无法解决它。
为了论证,我认为它不会那样。
你可以从'AA'开始并'增加'就像这样:
AB AC ... AZ BA BB BC ...等
要做到这一点,你可以玩工厂女孩的序列(使用模数和分数):
sequence(:alpha) do |n|
('a'..'z').to_a[n / 26] + ('a'..'z').to_a[n % 26]
end
答案 2 :(得分:0)
这比使用序列效率低(因为它需要数据库读取),但效果很好:
FactoryGirl.define do
factory :country do
alpha do
loop do
possible_state = ('a'..'z').to_a.sample(2).join
break possible_state unless Country.exists?(alpha: possible_state)
end
end
end
end
另请注意使用sample
。