Rails:在创建时违反约束,但在更新时不违反

时间:2010-04-13 19:52:38

标签: ruby-on-rails oracle model constraints

注意:这是this question的“railsier”(更简洁)版本,有点长。

我在生产服务器上获得Rails行为,我无法在开发服务器上复制。除了凭据和缓存设置之外,代码库是相同的,并且两者都由具有相同模式(但不同数据)的Oracle 10g数据库提供支持。

我的Rails应用程序包含一个用户模型,其中包含_one注册;通过registration_ownerships表注册has_and_belongs_to_many company_ownerships。注册后,用户会填写与所有三种模型相关的数据,包括一系列复选框,表明注册所有权可能适用于他们的帐户。

在开发服务器上,无论输入什么数据,注册过程都是无缝的。但是,在生产时,如果用户在提交注册之前检查任何公司所有权字段,Oracle会抱怨对company_ownerships表的主键(基于company_ownership_id和registration_id的双字段键)和用户的约束违规获取标准的Rails 500错误屏幕。在每种情况下,我都确认生产数据库中没有这两个字段的冲突记录,所以我不知道为什么会违反约束。

为了进一步混淆事情,如果用户在没有列出任何所有权的情况下注册并稍后返回并修改其帐户以反映所有权数据(通过相同的界面完成),则应用程序很乐意遵守他们的请求并且Oracle很好 - 表现得很好(这是生产和开发)。

我花了几天的时间试图弄清楚可能导致这个问题的原因,并且我的智慧已经到了尽头。任何建议将不胜感激!

更新4/15/10:我刚刚注意到一些可能有用的东西。我尝试在开发和生产中注册相同的帐户,并故意将“电话”字段留空,这是必填字段。在dev上,我收到了以下消息:

  

1错误禁止此注册被保存

     

以下字段存在问题:

     
      
  • 手机不能为空
  •   

然而,在制作方面,我明白了:

  

2个错误禁止此注册被保存

     

以下字段存在问题:

     
      
  • 手机不能为空
  •   
  • 手机不能为空
  •   

我的猜测是,这与生产中违反的约束直接相关 - 可能作为提交的一部分,字段被插入一次,然后再次插入但是第二次违反约束然后回滚整个事务,删除所有初始插入的证据。关于可能导致这种行为的任何想法,无论是在Rails方面还是在Oracle方面?

2 个答案:

答案 0 :(得分:1)

首先,检查应用程序是否正在连接到您认为正在连接的数据库。

其次,检查数据类型,包括数字精度。例如,在以下示例中,小数位被静默截断,因此第二个插入失败并显示重复键

create table test_pk (pk_1 number(3,0), pk_2 number(3,0), val varchar2(20));
alter table test_pk add constraint test_pk_pk primary key (pk_1, pk_2);
insert into test_pk values (10.1, 10.1, 'test 10.1');
insert into test_pk values (10.2, 10.2, 'test 10.2');

最坏的情况是,禁用约束,尝试操作,然后重新启用约束。这将告诉你是否确实存在一些重复的数据。可能会出现一些奇怪的竞争条件,包括连接池和非立即操作(例如插入连接a,删除连接b,在连接b之前插入连接b)已经承诺。)

答案 1 :(得分:0)

碰巧的是,目录周围有一个“注册”模型的备用副本;即使它有一个不同的名称(“registrations_2349871.rb”或类似的东西)Rails运行所有模型功能(保存,验证等)两次,因此违反了键约束!我以前从未见过这样的行为。删除流氓文件解决了这个问题。