解决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文件,分别为:

Yml代码  
  1. image1:  
  2.   id: 1  
  3.   locations: china  

 

Yml代码  
  1. china:  
  2.   name:china  

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

Ruby代码  
  1. The INSERT statement conflicted with the FOREIGN key constraint ......  

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

 

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

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

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

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

测试发现,运行正常。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值