我的插值:我不确定我是否可以将它与 Faker 一起使用
插值适用于任何表达式。甚至是多个陈述。 "#{ a = 1 + 1; b = 2 + 2; a + b}" 将产生 "6"。但不要那样做,这会令人困惑。
name: "#{Faker::Verb.ing_form} service",
等价于
name: Faker::Verb.ing_form.to_s + " service"
在一些地方你错过了插值。
bio = "Hi, I'm #{user.username}. Faker::Movie.quote"
应该是……
bio = "Hi, I'm #{user.username}. #{Faker::Movie.quote}"
在其他地方不需要插值。
search_terms: ["#{Faker::Verb.ing_form}"]
Faker::Verb.ing_form 已经返回一个字符串,不需要插值。
search_terms: [Faker::Verb.ing_form]
我想使用用户名和电子邮件中给出的相同用户名,我这样做对吗?
不,您不能引用user,直到它已经被创建。如果你尝试,你会得到类似undefined method `username' for nil:NilClass 的东西。 user 是 nil 和 nil 没有名为 username 的方法。
您可以创建一个用户,设置其电子邮件,然后保存。
user = User.new(
username: Faker::DcComics.hero,
password: "123456",
avatar: Faker::LoremFlickr.image(size: "900x900", search_terms: ['dccomics'])
)
user.email = "#{user.username}@gmail.com"
user.bio = "Hi, I'm #{user.username}. #{Faker::Movie.quote}"
user.save!
或者您可以先创建用户名并将其存储在变量中以供参考。
username = Faker::DcComics.hero
user = User.create!(
username: username,
password: "123456",
email: "#{username}@gmail.com",
bio: "Hi, I'm #{username}. #{Faker::Movie.quote}",
avatar: Faker::LoremFlickr.image(size: "900x900", search_terms: ['dccomics'])
)
我的用户模型在 DB 表中没有头像,但是 has_one_attached :avatar,我可以给它一个种子吗?
我对@987654321@ 不是很熟悉,但我认为它应该像你写的那样工作。
我想从上面创建的其中一个中为我的服务模型提供一个随机 user_id,我真的不知道我该如何继续...
简单的是使用sample。
user = User.all.sample
我们可以使用pluck 仅获取 ID 来改善这一点。
user = User.pluck(:id).sample
但是,这会加载所有用户。对于小型测试数据库来说,这不是问题。对于生产代码,这是一种巨大的浪费。相反,我们可以使用order by random() limit 1。在 Rails 6 中它有点笨重。
User.order(Arel.sql('RANDOM()')).pluck(:id).first
请参阅this answer 以获得解释。
请注意,如果您已经加载了用户,请传递用户,而不是其 ID。这避免了服务必须再次加载用户。
10.times do
user = User.order(Arel.sql('RANDOM()')).pluck(:id).first
service = Service.create!(
...
user: user
)
end
但是有更好的方法...
关于我的服务模型的相关问题(has_many_attached :photos)。如何为它生成多张图片?
在这里,我们实现了真正的飞跃。不要生成静态测试数据,而是使用工厂。 FactoryBot 可以轻松定义“工厂”以使用 Faker 生成测试数据。你已经成功了一半。而FactoryBotRails 让 FactoryBot 了解如何使用 Rails 模型。
用户工厂看起来像这样。
FactoryBot.define do
factory :user do
username { Faker::DcComics.hero }
password { "123456" }
email { "#{username}@gmail.com" }
bio { "Hi, I'm #{username}. #{Faker::Movie.quote}" }
avatar { Faker::LoremFlickr.image(size: "900x900", search_terms: ['dccomics']) }
end
end
请注意,我们可以根据username 创建一个email。属性可以引用其他属性。那是因为属性实际上是有点像这样的小函数:
class UserFactory do
def username
@username ||= Faker::DDcComics.hero
end
def email
@email ||= "#{username}@gmail.com"
end
end
然后制作 10 个……
users = FactoryBot.create_list(:user, 10)
您可以覆盖默认值。如果您想要具有特定电子邮件地址的用户...
user = FactoryBot.create(:user, email: "c.kent@dailyplanet.com")
由于您可以即时创建用户,因此您不再需要播种特定数据。
现在服务。让我们看一下Service工厂。要创建服务,我们需要照片。
factory :service do
name { "#{Faker::Verb.ing_form} service" }
description { "I'll use my #{Faker::Superhero.power} to accomplish the mission" }
address { "#{Faker::Address.street_address}, #{Faker::Address.city}" }
user
# photos is presumably has-many_attached and so takes an Array.
photos {
[
Faker::LoremFlickr.image(
size: "900x900",
search_terms: [Faker::Verb.ing_form]
)
]
}
end
看看user。 FactoryBot 将自动填写使用您的用户工厂创建的用户。解决了用随机用户创建服务的问题。
我们的最后一步是通过DRY 定义我们的工厂来制作照片。
factory :photo, class: Faker::LoremFlickr do
size { "900x900" }
search_terms { Faker::Lorem.words }
initialize_with do
Faker::LoremFlickr.image(attributes)
end
end
这不是 Rails 模型,所以我们需要通过向 FactoryBot 提供其类和how to initialize it 来教它如何制作照片。 attributes 是一个包含 size 和 search_terms 的 Hash。
另外请注意,我使用了更通用的搜索词。需要特定搜索词的工厂将提供自己的搜索词。
我们可以制作任意数量的照片。
photos = FactoryBot.build_list(:photos, 3)
使用照片工厂,我们可以干掉用户和服务工厂。一切都在这里。
FactoryBot.define do
factory :photo, class: Faker::LoremFlickr do
size { "900x900" }
search_terms { Faker::Lorem.words }
initialize_with do
Faker::LoremFlickr.image(attributes)
end
end
factory :user do
username { Faker::DcComics.hero }
password { "123456" }
email { "#{username}@gmail.com" }
bio { "Hi, I'm #{username}. #{Faker::Movie.quote}" }
avatar { build(:photo, search_terms: ['dccomics']) }
end
factory :service do
name { "#{Faker::Verb.ing_form} service" }
description { "I'll use my #{Faker::Superhero.power} to accomplish the mission" }
address { "#{Faker::Address.street_address}, #{Faker::Address.city}" }
user
photos {
build_list(:photo, 3, search_terms: [Faker::Verb.ing_form])
}
end
end
现在,当您需要一项服务进行测试时,您可以要求提供。
service = FactoryBot.create(:service)
想要使用不同名称的服务?
service = FactoryBot.create(:service, name: "Universal Exports")
没有照片怎么办?
service = FactoryBot.create(:service, photos: [])
这只是 FactoryBot 功能的皮毛。
工厂比种子文件更灵活方便。