我尝试使用rails Faker gem生成唯一的产品名称,以便在数据库中生成样本Item模型。我多次使用过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
答案 0 :(得分:3)
要获得唯一的name
,请将faker括在括号中。例如
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
在您的spec文件中
let(:item) { create_list(:item, 98) }
答案 1 :(得分:0)
您可以在模型中添加validates_uniqueness_of :name
。当你运行种子方法时,如果已存在相同的名称,它将抛出错误并跳到下一个。
您可能不会完全拥有98 Items
。您可以增加次数或编辑Faker本身。
答案 2 :(得分:0)
我在经过一些实验后想通了,显然循环在某种程度上就像范围一样起作用。如果在循环中初始化局部变量,则循环外部的函数将看不到它。在这种情况下,name
始终从Item
函数返回字符串Item.nameMaker
。因此,第一次尝试总是成功,第二次尝试将获得验证限制。
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