解决Rails rake fixtures加载的顺序问题

Rails中有个rake rask,叫做 db:fixtures:load,可以帮你自动load指定目录下(text/fixtures)的yml或csv文件。然而,如果这些文件之间有依赖关系,这个task会失败。

比如有两个模型Image和Locations,依赖关系为:Image has_and_belongs_to_many Locations 的单向关联。

数据库中分别对应Images和Locations表,并通过image_category_rel表关联。

在test/fixtures目录下有这两个模型的yml文件,分别为:

image1:
  id: 1
  locations: china

 

china:
  name:china

如果db:fixtures:load先加载category文件,然后加载images文件,肯定没问题。不幸的是,我们使用时出现了这样的错误:

The INSERT statement conflicted with the FOREIGN key constraint ......

经过进一步测试,发现就是load时首先加载了images文件,插入中间表时无法找到对Locations表的关联。

 

所以解决yml文件的加载顺序就可以。上网google了一下,已经有人遇到了同样的问题,而且incognito 给了一个这样的task:

task :load_fixtures_ordered => :environment do
  require 'active_record/fixtures'  
  ordered_fixtures = Hash.new
  ENV["FIXTURE_ORDER"].split.each { |fx| ordered_fixtures[fx] = nil }
  other_fixtures = Dir.glob(File.join(RAILS_ROOT, 'test', 'fixtures', '*.{yml,csv}')).collect { |file| File.basename(file, '.*') }.reject {|fx| ordered_fixtures.key? fx }
  ActiveRecord::Base.establish_connection(ENV['RAILS_ENV'])
  (ordered_fixtures.keys + other_fixtures).each do |fixture|
    Fixtures.create_fixtures('test/fixtures',  fixture)
  end unless :environment == 'production' 
end

觉得写的有些麻烦了,于是和小龙一块整了一个简单一点的,如下:

task :load_ordered => :environment do
      require 'active_record/fixtures'
      ActiveRecord::Base.establish_connection(RAILS_ENV.to_sym)
      ordered = %w( location image )
      (ordered + Dir.glob(File.join(RAILS_ROOT, 'test', 'fixtures', '*.{yml,csv}')).collect { |file| File.basename(file, '.*') }).uniq.each do |fixture_name|
        Fixtures.create_fixtures('test/fixtures', fixture_name)
      end unless :environment == 'production'
 end

测试发现,运行正常。

这个任务主要用到了数组的+、uniq方法,觉得比incognito上面更简单一些。

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值