lazybios

使用Factory Girl Traits表示多对多关系 | Ruby

使用Factory Girl Traits表示多对多关系 Ruby

在开发Web应用时,使用关系型数据库建模,经常出现多对多的关联关系,在Rails中多对多可以用过has_and_belongs_to_manyhas_many,through实现,对于程序编写固然方便,但在测试中又该如何体现它们的关系呢?今天这篇就来说说如何用Factory Girl固件表示has_many,through的关系。关系描述如下:

class GpsPosition < ActiveRecord::Base
  has_many :gps_trackings
  has_many :modem_registries, through: :gps_trackings
end

class ModemRegistry < ActiveRecord::Base
  has_many :gps_trackings
  has_many :gps_positions, through: :gps_trackings
end

class GpsTracking < ActiveRecord::Base
  belongs_to :modem_registry
  belongs_to :gps_position
end

使用Traits

Factory Girl自带trait关键字,可以使用trait来表示一个模型的不同状态,然后利用after 钩子方法来创建关联,如下代码

FactoryGirl定义
FactoryGirl.define do
  factory :gps_position do
    gps_location 'POINT(-83.64753 40.80664)'
  end

  factory :modem_registry do
    wireless_system 'CDMA'

    trait :with_gps_position do
      after(:create) do |modem_registry|
        modem_registry.gps_positions << create(:gps_position)
      end
    end
  end
end
使用
another_gps_position = create(:gps_position)
create(:modem_registry_with_gps_position, gps_position: another_gps_position)

除了create外,还可以通过create_list来创建整个集合的关联关系,如下:

trait :with_gps_positions do
  ignore do
    number_of_gps_positions 1
  end

  after(:create) do |modem_registry, evaluator|
    create_list(:gps_tracking, evaluator.number_of_gps_positions, modem_registry: modem_registry)
  end
end
使用
create(:modem_registry, :with_gps_positions)
#=> will create 1 modem_registry with 1 gps_position

create(:modem_registry, :with_gps_positions, number_of_gps_positions: 10)
#=> #=> will create 1 modem_registry with 10 gps_positions

嗯,如你所见,这篇文章更像是个代码碎片,没错,有时候其实代码比文字更直观,特别是你只想知道该怎么做的时候!最后,还是要提一下,本文是译译自参考引用处的博文,需要看原文自行取阅。

-完-

参考引用

微信关注「日拱一卒」公众号