如何使FactoryGirl.create影响另一个记录的属性?

order.save商店应用程序中,通常在预订产品之后, bookings_controller创建操作会执行order.save ,而order.save又会激活必要的before_save方法order.sum_of_all_bookings

在为查看订单列表的管理员构建RSpec测试时,进行预订不会更改订单总数。 索引在浏览器中有效。

 require 'rails_helper' RSpec.feature 'Admin can oversee orders' do let(:admin) { FactoryGirl.create(:user, :admin) } let(:customer) { FactoryGirl.create( :user ) } let!(:order_1) { FactoryGirl.create( :order, customer: customer ) } let!(:booking_1) { FactoryGirl.create( :booking, product_name: 'Honingpot', product_quantity: 1, product_price: '5,00', order: order_1 ) } let!(:order_2) { FactoryGirl.create( :order, customer: customer ) } let!(:booking_2) { FactoryGirl.create( :booking, product_name: 'Streekpakket', product_quantity: 2, product_price: '10,00', order: order_2 ) } before do order_1.sum_all_bookings order_2.sum_all_bookings login_as(admin) visit orders_path end scenario 'with success' do within('table#paid') do expect(page).to have_content '5,00' expect(page).to have_content '10,00' end end end 

在块之前不起作用。

工厂女孩创建后也没有:

 FactoryGirl.define do factory :booking do product_name 'Honingpot' product_quantity '1' product_price '3,99' order after(:create) { |booking| booking.order.save } # booking.order.sum_all_bookings, also not working end end 

RSpec打印订单中的预订,但订单总数不变。

如何订单总和预订?

或者更一般地说:

如何使FactoryGirl.create影响另一个记录的属性?

清理您的规格

首先,您的规格中有太多的工厂配置。 FactoryGirl可以将您的创建和设置从您的规范中移开

这不会直接解决您的问题,但这些步骤将使您的测试过程更清晰,更简单,更快捷。

1. Faker Gem

要开始改造,请继续添加faker gem,以便您可以轻松地为工厂生成有用的随机数据。

 FactoryGirl.define do factory :booking do product_name { Faker::Commerce.product_name } product_quantity { Faker::Number.number(2) } product_price Faker::Number.decimal(2) order end end 

你去,一些准备好的预订工厂准备使用。

2.特质

它们是在某些情况下调整工厂的好方法。 绝对在文档中阅读更多关于它们的内容 。

 FactoryGirl.define do factory :order do customer trait :with_bookings do after(:create) do |order| order.bookings << create_list(:booking, 2) end end end end 

所以现在您可以轻松创建包含或不包含预订的订单:

 let(:order_with_bookings) { create(:order, :with_bookings) } 

3.更清晰的语法

您可以FactoryGirl语法,只需create(:order) 。 完成这些步骤后,您应该拥有更清洁的测试环境。

解决回调问题

据我了解,你设置你的回调如下:

 class Order has_many :bookings before_save :update_order_cache def update_order_cache # calculation of the total bookings sum end end class Booking belongs_to :order end 

但是你应该反过来做,在产品创建或更新后,应该触发订单上的回调:

 class Order has_many :bookings def update_order_cache # calculation of the total bookings sum end end class Booking belongs_to :order after_save do order.update_order_cache end end 

如果该字段永远不应为空,您还可以向总和添加默认值。

 validates :sum_field, presence: true, default: '0.0' 

这应该包括你。 干杯!