Ruby on rails 如何使我的种子正常工作?
我还是Ruby/Rails新手,在运行命令Rails db:seed之前,我需要您的帮助来确保我的seed是好的 这是我的种子:Ruby on rails 如何使我的种子正常工作?,ruby-on-rails,ruby,Ruby On Rails,Ruby,我还是Ruby/Rails新手,在运行命令Rails db:seed之前,我需要您的帮助来确保我的seed是好的 这是我的种子: require 'faker' puts "Creating 10 fake user heros..." 10.times do user = User.create!( username: Faker::DcComics.hero, password: "123456", email: &quo
require 'faker'
puts "Creating 10 fake user heros..."
10.times do
user = User.create!(
username: Faker::DcComics.hero,
password: "123456",
email: "#{user.username}@gmail.com",
bio: "Hi, I'm #{user.username}. Faker::Movie.quote",
avatar: Faker::LoremFlickr.image(size: "900x900", search_terms: ['dccomics'])
)
puts "#{user.username} created!"
end
puts "Creating 10 fake hero services..."
10.times do
service = Service.create!(
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}",
photos: Faker::LoremFlickr.image(size: "900x900", search_terms: ["#{Faker::Verb.ing_form}"]),
user_id: rand(user.id)
)
puts "#{service.name} created!"
end
puts "Finished!"
我想我会有几个问题,尤其是:
我的插言:我不确定我是否被允许与Faker一起使用它
我想使用用户名和电子邮件中给出的相同用户名,对吗?
我的用户模型在DB表中没有头像,但是附加了一个:头像,我可以给它一个种子吗?
有关我的服务模式的相关问题,请参见附件:照片。如何为它生成多张图片?
我想给我的服务模型一个随机的用户id,我真的不知道如何继续。。。
在中止消息中,必须有种子失败的特定行。可能是电子邮件。如果用户名是:小丑怎么办?电子邮件不能是Joker@gmail.com@
试试这个:
require 'faker'
puts "Creating 10 fake user heros..."
10.times do
user = User.create!(
username: Faker::DcComics.hero,
password: "123456",
email: "#{username..gsub(/\s+/, "").downcase}@gmail.com",
bio: "Hi, I'm #{user.username}. #{Faker::Movie.quote}"
)
puts "#{user.username} created!"
end
在中止消息中,必须有种子失败的特定行。可能是电子邮件。如果用户名是:小丑怎么办?电子邮件不能是Joker@gmail.com@
试试这个:
require 'faker'
puts "Creating 10 fake user heros..."
10.times do
user = User.create!(
username: Faker::DcComics.hero,
password: "123456",
email: "#{username..gsub(/\s+/, "").downcase}@gmail.com",
bio: "Hi, I'm #{user.username}. #{Faker::Movie.quote}"
)
puts "#{user.username} created!"
end
我的插言:我不确定我是否被允许与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_表单已返回字符串,不需要插值
search_terms: [Faker::Verb.ing_form]
我想使用用户名和电子邮件中给出的相同用户名,对吗
不,在创建用户之前,不能引用该用户。如果您尝试,您将得到类似于nil:NilClass的未定义方法“username”。用户为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表中没有头像,但是附加了一个:头像,我可以给它一个种子吗
我不太熟悉,但我认为它应该像你写的那样工作
我想给我的服务模型一个随机的用户id,我真的不知道如何继续
最简单的是使用
我们可以使用Pull来获取ID,从而使这一点变得更好
user = User.pluck(:id).sample
但是,这会加载所有用户。对于一个小的测试数据库,这不是问题。对于生产代码来说,这是一个巨大的浪费。相反,我们可以使用顺序随机限制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
但是有一个更好的方法
有关我的服务模式的相关问题,请参见附件:照片。如何为它生成多张图片
在这里,我们实现了真正的飞跃。使用工厂,而不是生成静态测试数据。使用Faker可以轻松定义工厂以生成测试数据。你已经走到一半了。并让FactoryBot了解如何跟踪模型
用户工厂应该是这样的
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
请注意,我们可以根据用户名发送电子邮件。属性可以引用其他属性。这是因为属性实际上是类似这样的小函数:
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")
由于您可以动态创建用户,因此不再需要为特定的数据播种
现在开始服务。我们来看看服务工厂。为了提供服务,我们需要照片
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
看看用户。FactoryBot将自动使用您的用户factory创建的用户来填充该内容。解决了随机用户提供服务的问题
我们的最后一步是通过定义一个制作照片的工厂来提升我们的工厂
factory :photo, class: Faker::LoremFlickr do
size { "900x900" }
search_terms { Faker::Lorem.words }
initialize_with do
Faker::LoremFlickr.image(attributes)
end
end
这不是Rails模型,所以我们需要通过提供类和类来教FactoryBot如何制作照片。属性是包含大小和搜索项的哈希
还请注意,我使用了更通用的搜索词。需要特定搜索条件的工厂将提供自己的搜索条件
我们想拍多少就拍多少
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能做什么的表面
工厂比种子文件更灵活、更方便
我的插言:我不确定我是否被允许与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_表单已返回字符串,不需要插值
search_terms: [Faker::Verb.ing_form]
我想使用用户名和电子邮件中给出的相同用户名,对吗
不,在创建用户之前,不能引用该用户。如果您尝试,您将得到类似于nil:NilClass的未定义方法“username”。用户为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表中没有头像,但是附加了一个:头像,我可以给它一个种子吗
我不太熟悉,但我认为它应该像你写的那样工作
我想给我的服务模型一个随机的用户id,我真的不知道如何继续
最简单的是使用
我们可以使用Pull来获取ID,从而使这一点变得更好
user = User.pluck(:id).sample
但是,这会加载所有用户。对于一个小的测试数据库,这不是问题。对于生产代码来说,这是一个巨大的浪费。相反,我们可以使用顺序随机限制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
但是有一个更好的方法
有关我的服务模式的相关问题,请参见附件:照片。如何为它生成多张图片
在这里,我们实现了真正的飞跃。使用工厂,而不是生成静态测试数据。使用Faker可以轻松定义工厂以生成测试数据。你已经走到一半了。并让FactoryBot了解如何跟踪模型
用户工厂应该是这样的
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
请注意,我们可以根据用户名发送电子邮件。属性可以引用其他属性。这是因为属性实际上是类似这样的小函数:
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")
由于您可以动态创建用户,因此不再需要为特定的数据播种
现在开始服务。我们来看看服务工厂。为了提供服务,我们需要照片
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
看看用户。FactoryBot将自动使用您的用户factory创建的用户来填充该内容。解决了随机用户提供服务的问题
我们的最后一步是通过定义一个制作照片的工厂来提升我们的工厂
factory :photo, class: Faker::LoremFlickr do
size { "900x900" }
search_terms { Faker::Lorem.words }
initialize_with do
Faker::LoremFlickr.image(attributes)
end
end
这不是Rails模型,所以我们需要通过提供类和类来教FactoryBot如何制作照片。属性是包含大小和搜索项的哈希
还请注意,我使用了更通用的搜索词。需要特定搜索条件的工厂将提供自己的搜索条件
我们想拍多少就拍多少
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能做什么的表面
工厂比种子文件更加灵活和方便。您有开发和测试数据库,如果出现问题,可以删除和重新创建这些数据库。试试看!嗨,Schwern,是的!我试图启动我的种子,但是我得到了rails abortedmessage,我不知道为什么rails abortedmessage附带了一条错误消息,其中有一个大堆栈跟踪,跟踪调用了哪些方法来获取错误。轨道里面有很多东西。别理它。查看代码中的部分,如db/seed.rb或app/models/user.rb,忽略其余部分。这可能是nil:NilClass的未定义方法“username”。您有开发和测试数据库,如果出现问题,可以删除并重新创建这些数据库。试试看!嗨,Schwern,是的!我试图启动我的种子,但是我得到了rails abortedmessage,我不知道为什么rails abortedmessage附带了一条错误消息,其中有一个大堆栈跟踪,跟踪调用了哪些方法来获取错误。轨道里面有很多东西。别理它。查看代码中的部分,如db/seed.rb或app/models/user.rb,忽略其余部分。这可能是nil:NilClass.Thx的未定义方法“username”。对于您的答案Yshmarov,您是对的,它首先来自我尝试代码的电子邮件,但我仍然有一条错误消息:NameError:未定义的局部变量或main:Object的方法“username”。顺便说一句,你为什么要使用split?使用Joker.gsub/\s+/,.downcase?split只是一个如何修改用户名的示例。实际上,您的gsub方法非常好。Joker.gsub/\s+/,.downcase=>thejokerOk让人感觉
E谢谢你的帮助!Thx对于你的答案Yshmarov,你是对的,它首先来自我尝试你的代码的电子邮件,但我仍然有一个错误消息:NameError:undefined局部变量或main:Object的方法“username”。顺便说一句,你为什么要使用split?使用Joker.gsub/\s+/,.downcase?split只是一个如何修改用户名的示例。实际上,您的gsub方法非常好。Joker.gsub/\s+/,.downcase=>thejokerOk是有意义的。谢谢你的帮助!哦,哇,谢谢你的解释,这真的很有帮助而且非常有趣,我学到了很多!我将尝试在我的应用程序中使用factory,它看起来真的很简单,再次感谢Schwern!吹毛求疵,但属性更像def username@用户名| |=Faker::DDcComics.hero;结束,也就是说,他们会记住他们的价值,这样你就可以在整个工厂重复使用。哦,哇,感谢所有的解释,这真的很有帮助,非常有趣,我学到了很多!我将尝试在我的应用程序中使用factory,它看起来真的很简单,再次感谢Schwern!吹毛求疵,但属性更像def username@用户名| |=Faker::DDcComics.hero;结束,也就是说,他们会记住他们的价值,这样你就可以在整个工厂重复使用。