Rails faker gem产生相同的产品名称

时间:2015-03-22 05:51:37

标签: ruby-on-rails ruby-on-rails-4 random-sample faker

我尝试使用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

3 个答案:

答案 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