为什么pg gem自动投射' A'对于整数类型,为0

时间:2015-03-11 22:51:04

标签: ruby-on-rails postgresql rails-activerecord

我在Postgresql中有一个定义为整数的列,并编写了一个测试来分配字符'A',并期望抛出一个数据库错误。

然而,pg似乎会自动将字符映射为'0'。

我无法想到这个功能的任何正当理由,我倾向于认为覆盖隐式约束是一个坏主意,即整数应该是一个整数。

我在这里错过了一些大图吗?

更新

感谢您的快速回复(mu_is_too_short)。你是对的'A'.to_i返回0而0是一个有效值,所以CHECK无济于事。我将在模型中进行数值验证,所以我认为这并不重要。只是我试图检查数据库列是否正确配置为整数。我认为Rspec测试确实是针对数据库上方的层。

再次更新......

我创建了以下类:

class Notaninteger

  def initialize(par)
    @par = par
  end

  def to_i
    @par
  end

end

我认为这可能会对抗AR试图调用to_i的尝试。但是,这似乎不起作用。 Drat,又被挫败了!

最后一次更新......

以下作品:

class Notaninteger

  def to_i
    self
  end

end

我怀疑AR可能多次调用to_i,而且上面总是会返回一个Notaninteger对象。

2.1.4 :002 > range.start_of_range = 'A'
=> "A" 
2.1.4 :003 > range.save!
(0.4ms)  BEGIN SQL (11.6ms)  INSERT INTO "coderanges" ("comment", "created_at", "end_of_range", "groupname", "name", "protection", "start_of_range", "updated_at") VALUES ($1, $2, $3, $4, $5, $6, $7, $8) RETURNING "id"  [["comment", nil], ["created_at", Wed, 11 Mar 2015 21:46:52 UTC +00:00], ["end_of_range", nil], ["groupname", nil], ["name", nil], ["protection", nil], ["start_of_range", 0], ["updated_at", Wed, 11 Mar 2015 21:46:52 UTC +00:00]]

1 个答案:

答案 0 :(得分:0)

这不是执行转换的pg gem,当你执行to_i赋值时,ActiveRecord会在字符串上调用range.start_of_range = 'A'。 AR正在调用to_i,因为据推测,该列是一个整数。

如果零不是start_of_range的有效值,那么你应该添加一个验证来检查它(如果你像我一样正常偏执,在数据库中添加一个CHECK约束来匹配你的验证)