如何使用Fabricate-gem生成对象?

时间:2016-10-03 04:30:33

标签: ruby-on-rails ruby-on-rails-4.2 faker fabrication-gem

我使用的是Rails 4,FabricateFaker宝石。我试图用(100个左右)随机创建的对象(包含最多3个冰淇淋的订单)为我的数据库播种。我跟着建议使用这种方法的This Answer

模型/ order.rb

  class Order < ActiveRecord::Base
    ...
    has_many :ice_creams
    ...
  end

模型/ ice_cream.rb

  class IceCream < ActiveRecord::Base
    ...
    has_and_belongs_to_many :flavors
    has_many :added_extras
    has_many :extras, :through => :added_extras
    belongs_to :order
    ...
  end

模型/ extra.rb

  class Extra < ActiveRecord::Base
    ...
    has_many :added_extras
    has_many :extras, :through => :added_extras
    ...
  end

测试/制造者/ order_fabricator.rb

  Fabricator(:order) do

    user { User.offset(rand(User.count)).first } #fine
    shift { Shift.offset(rand(Shift.count)).first } #fine
    created_at { Faker::Date.backward(365) } #fine
    ice_creams(rand: 3) { |attrs| Fabricate( :ice_cream, created_at: attrs[:created_at] ) } #fine

    total { Faker::Number.between(5, 25) }
    #add more logic depending of the total number of randomly created ice creams

    discount { [0, 10, 15, 25].sample } #fine
    total_after_discount { |order| order[:total] -  ( (order[:total] * order[:discount]) / 100 ) }
    paid { [50, 100, 200].sample } #fine
    remaining { |order| order[:paid] -  order[:total_after_discount] } #fine

  end

测试/制造者/ ice_cream_fabricator.rb

  Fabricator(:ice_cream) do

    size { Size.offset(rand(Size.count)).first } #fine
    basis { Basis.offset(rand(Basis.count)).first } #fine
    sauce { Sauce.offset(rand(Sauce.count)).first } #fine
    topping { Topping.offset(rand(Topping.count)).first } #fine

    flavors { [ Flavor.offset(rand(Flavor.count)).first ] }
    #add additional ability to be one or two flavors randomly

    extras { [ Extra.offset(rand(Extra.count)).first ] }

    ice_cream_price { [15, 17, 18, 19, 20, 22].sample } #add logic
    extras_price { [5, 10, 15, 20 ].sample } #add logic 

    total_price { |attrs| attrs[:ice_cream_price] + attrs[:extras_price] } #fine
    created_at { Faker::Date.backward(365) }

  end

它工作正常,我现在可以创建假的订单,其中包含最多3个伪造的冰淇淋,但事情是我正在碾压到弄清楚制作更逼真的订单的逻辑,正如您在我的制造商代码中注意到的那样,有一些属性我标记得很好 - 我对它的结果很好 - 并且一些我还没有完全满意的,比如......

  • 我希望Fabricated Ice Cream 可以随机拥有一两种口味。
  • 我希望使用Extras
  • 做同样的事情
  • 我想将随机制作的 Ice Creams :total_price的总和作为:total
  • 传递给订单

我试图通过创建风味制作者来实现这一目标,但它没有工作..

测试/制造者/ flavor_fabricator.rb

  Fabricator(:flavor) do
    Flavor.offset(rand(Flavor.count)).first
  end

我还尝试将:total_price与activeRecord方式相加,但它也没有工作

测试/制造者/ order_fabricator.rb

  Fabricator(:order) do
    ...
    total { self.ice_creams.sum(:total_price) }
    ...
  end

所以我的问题是...... - 我希望的东西是可能的还是它太多了?如果是这样,如何实现呢?

我希望自己清楚明白,你可以帮助我。感谢

1 个答案:

答案 0 :(得分:1)

您似乎正在尝试使用制作来设置模型的计算值,例如IceCream#total_price。你应该让你的模型上的方法做他们的事情,比如从部件中计算总数,而不是试图用制造强制它们。

具体回答您的问题:

1)我希望制作的冰淇淋可以随机拥有一种或两种口味。

Fabricator(:ice_cream) do
  flavors { Flavor.all.sample(rand(1..2)) }
end

2)与#1相同

3)你应该在Order上有一个方法来计算创建时的总数。