Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 如何使我的种子正常工作?_Ruby On Rails_Ruby - Fatal编程技术网

Ruby on rails 如何使我的种子正常工作?

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

我还是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: "#{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;结束,也就是说,他们会记住他们的价值,这样你就可以在整个工厂重复使用。