Rails faker gem 生产相同的产品名称
Rails faker gem produces same product name
我正在尝试使用 rails Faker gem 来生成唯一的产品名称,以便在数据库中制作示例项目模型。我已经多次使用 Faker,但出于某种原因我无法产生新的产品名称。我已经制作了 nameMaker 函数以避免可能的早期重复,但我在一次插入后得到了一个记录失效。有谁知道我该如何解决这个问题?
seed.rb:
98.times do |n|
name = Item.nameMaker
description = Faker::Lorem.sentence(1)
price = Item.priceMaker
item = Item.create!(
name: name,
description: description,
price: price)
end
item.rb:
class Item < ActiveRecord::Base
validates :name, presence: true, length: { maximum: 100 }
validates :description, presence: true,
length: { maximum: 1000 }
VALID_PRICE_REGEX = /\A\d+(?:\.\d{0,3})?\z/
validates :price, presence: true,
:format => { with: VALID_PRICE_REGEX },
:numericality => {:greater_than => 0}
validates_uniqueness_of :name
def Item.nameMaker
loop do
name = Item.newName
break if Item.find_by(name: name).nil?
end
return name
end
def Item.newName
Faker::Commerce.product_name
end
end
您可以在模型中添加 validates_uniqueness_of :name
。当你 运行 seed 方法时,如果已经存在相同的名称,它会抛出错误并跳到下一个。
您可能不会正好有 98 Items
。您可以增加次数或编辑 Faker 本身。
经过一些实验我弄明白了,显然循环在某些方面就像一个函数一样作用域。如果在循环中初始化局部变量,循环外的函数将看不到它。在这种情况下,name
总是从 Item.nameMaker
函数返回字符串 Item
。因此,第一次尝试总是会成功,而第二次尝试将获得验证限制。
def Item.nameMaker
loop do
name = Faker::Commerce.product_name # 'Random Product Name'
puts "Name: #{name}" # "Name: Random Product Name"
item = Item.find_by(name: name)
if item.nil?
puts "#{name} not found" # "Random Product Name not found"
break
else
end
end
puts "Returning Name #{name}" # "Returning Name Item"
return name
end
我设法通过在循环外初始化局部变量来解决这个问题。通过这样做,出于某种原因,整个函数现在对同一个局部变量具有可见性。
def Item.nameMaker
name = "" #initializing
loop do
name = Faker::Commerce.product_name # 'Random Product Name'
puts "Name: #{name}" # "Name: Random Product Name"
item = Item.find_by(name: name)
if item.nil?
puts "#{name} not found" # "Random Product Name not found"
break
else
end
end
puts "Returning Name #{name}" # "Returning Random Product Name"
return name
end
要获得独一无二的 name
,请将伪造者括在括号中。例如
name { Faker::Commerce.product_name }
为此,您还可以使用工厂女孩,当您想要创建 98 个不同的项目时,您可以使用
factories/item.rb
FactoryGirl.define do
factory :item do
name { Faker::Commerce.product_name }
description { Faker::Lorem.sentence(1) }
price Faker::Commerce.price
end
end
在您的规范文件中
let(:item) { create_list(:item, 98) }
我正在尝试使用 rails Faker gem 来生成唯一的产品名称,以便在数据库中制作示例项目模型。我已经多次使用 Faker,但出于某种原因我无法产生新的产品名称。我已经制作了 nameMaker 函数以避免可能的早期重复,但我在一次插入后得到了一个记录失效。有谁知道我该如何解决这个问题?
seed.rb:
98.times do |n|
name = Item.nameMaker
description = Faker::Lorem.sentence(1)
price = Item.priceMaker
item = Item.create!(
name: name,
description: description,
price: price)
end
item.rb:
class Item < ActiveRecord::Base
validates :name, presence: true, length: { maximum: 100 }
validates :description, presence: true,
length: { maximum: 1000 }
VALID_PRICE_REGEX = /\A\d+(?:\.\d{0,3})?\z/
validates :price, presence: true,
:format => { with: VALID_PRICE_REGEX },
:numericality => {:greater_than => 0}
validates_uniqueness_of :name
def Item.nameMaker
loop do
name = Item.newName
break if Item.find_by(name: name).nil?
end
return name
end
def Item.newName
Faker::Commerce.product_name
end
end
您可以在模型中添加 validates_uniqueness_of :name
。当你 运行 seed 方法时,如果已经存在相同的名称,它会抛出错误并跳到下一个。
您可能不会正好有 98 Items
。您可以增加次数或编辑 Faker 本身。
经过一些实验我弄明白了,显然循环在某些方面就像一个函数一样作用域。如果在循环中初始化局部变量,循环外的函数将看不到它。在这种情况下,name
总是从 Item.nameMaker
函数返回字符串 Item
。因此,第一次尝试总是会成功,而第二次尝试将获得验证限制。
def Item.nameMaker
loop do
name = Faker::Commerce.product_name # 'Random Product Name'
puts "Name: #{name}" # "Name: Random Product Name"
item = Item.find_by(name: name)
if item.nil?
puts "#{name} not found" # "Random Product Name not found"
break
else
end
end
puts "Returning Name #{name}" # "Returning Name Item"
return name
end
我设法通过在循环外初始化局部变量来解决这个问题。通过这样做,出于某种原因,整个函数现在对同一个局部变量具有可见性。
def Item.nameMaker
name = "" #initializing
loop do
name = Faker::Commerce.product_name # 'Random Product Name'
puts "Name: #{name}" # "Name: Random Product Name"
item = Item.find_by(name: name)
if item.nil?
puts "#{name} not found" # "Random Product Name not found"
break
else
end
end
puts "Returning Name #{name}" # "Returning Random Product Name"
return name
end
要获得独一无二的 name
,请将伪造者括在括号中。例如
name { Faker::Commerce.product_name }
为此,您还可以使用工厂女孩,当您想要创建 98 个不同的项目时,您可以使用
factories/item.rb
FactoryGirl.define do
factory :item do
name { Faker::Commerce.product_name }
description { Faker::Lorem.sentence(1) }
price Faker::Commerce.price
end
end
在您的规范文件中
let(:item) { create_list(:item, 98) }