rake test:units在SQL和Ruby DSL两种schema模式下的差异

sql方式,会复制development数据库中的外键。相反,在schema模式下的外键是被完全忽略的,即使开发数据库里有,也不会复制到test数据库里。

而test:units执行的时候是根据environment.rb里的config.active_record.schema_format = sql设置(注释掉时为ruby dsl模式)来判断用哪种模式的。通过使用rake test:units --trace我们可以看见两者的差别:(忽略invoke,只看execute)

ruby dsl模式的schema下执行的task:
** Invoke test:units (first_time)
** Invoke db:test:prepare (first_time)
** Invoke environment (first_time)
** Execute environment
** Execute db:test:prepare
** Invoke db:test:clone (first_time)
** Invoke db:schema:dump (first_time)
** Invoke environment
** Execute db:schema:dump
** Execute db:test:clone
** Invoke db:schema:load (first_time)
** Invoke environment
** Execute db:schema:load
** Execute test:units
...

sql模式的schema下执行的task:
** Invoke test:units (first_time)
** Invoke db:test:prepare (first_time)
** Invoke environment (first_time)
** Execute environment
** Execute db:test:prepare
** Invoke db:test:clone_structure (first_time)
** Invoke db:structure:dump (first_time)
** Invoke environment
** Execute db:structure:dump
** Invoke db:test:purge (first_time)
** Invoke environment
[b]** Execute db:test:purge [/b]
** Execute db:test:clone_structure
** Execute test:units

具体的task内部代码就不展开讨论了,关键差别是sql模式知道有外键存在,所以多了一个db:test:purge直接删整个数据库而不管表顺序一一删除的操作。而schema模式假设没有外键,只是简单用load。load这个操作就是删一个再建一个的,这某种程度上是ruby dsl风格的schema的限制所致(必须顺序执行,不能事先检查外键依赖关系)。

所以解决办法就是:先purge掉test数据库,然后设好config.active_record.schema_format要外键的用sql格式,不要外键用ruby dsl格式(但是has_many之类关联设置后面最好设一下:dependent参数)。然后直接用test:units,不用事先自己建立test表结构。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值