我的插值:我不确定我是否可以将它与 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,我可以给它一个种子吗?
我对Rails 中的附件不是很熟悉,但我认为它应该像你写的那样工作。
我想从上面创建的其中一个中为我的服务模型提供一个随机 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
请参阅此答案以获取解释。
请注意,如果您已经加载了用户,请传递用户,而不是其 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
请注意,我们可以基于email. username属性可以引用其他属性。那是因为属性实际上是有点像这样的小函数:
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 将自动填写使用您的用户工厂创建的用户。解决了使用随机用户创建服务的问题。
我们的最后一步是通过定义一个来制作照片来干燥我们的工厂。
factory :photo, class: Faker::LoremFlickr do
size { "900x900" }
search_terms { Faker::Lorem.words }
initialize_with do
Faker::LoremFlickr.image(attributes)
end
end
这不是 Rails 模型,因此我们需要通过向 FactoryBot 提供其类以及如何对其进行初始化来教 FactoryBot 如何制作照片。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 功能的皮毛。
工厂远比种子文件灵活方便。