我将 Rails 4 与 Postgres 数据库一起使用,但遇到一个问题,即前导零未保存在我的邮政编码列中。此列的数据类型是字符串。当我在 Rails 控制台中更新帐户的邮政编码时,从“7040”到“07040”,前导零,我被告知它已保存。但是,当我查找对象时,邮政编码仍然是“7040”,而不是“07040”。
我在 SO 上看到了这个问题,但答案建议重新启动您的服务器(我在没有改变行为的情况下完成了)并提到问题是在该用户的情况下列的数据类型曾经是整数。我的数据类型一直是字符串。
keep leading zeros when saving string in active record
您可以在下图中看到我在 Rails 控制台中执行这项工作的快照。我得到一个帐户。我用前导零保存 zip。保存似乎有效。然后我通过 ID 查找帐户并查找 zip 和尾随的“0”不保存:
我已经在此处更新了我的控制台图像并进行了保存!
rails console example with save!
我还对模型进行了这些验证:
验证 :contact_name, :company_name, :organization_id, :billing_address, :city, :state, :zip, presence: true
验证:account_number,唯一性:{scope: :organization_id}
另外,为了更具体地解决问题,我在下面进行了两项测试。非常奇怪的是,当测试 B 通过时,测试 A 失败了。所以这不是在前面保存 0 的问题——不知何故,我在保存一个前缀为“0”的字符串时遇到了问题。为什么会这样?我有很多 zip 需要更新,所以我不能像测试 B 那样手动设置它们 - 我需要找到一种方法以测试 A 的方式保存它们。
it 'TEST A' do
@a= create(:account, zip: '299')
new_zip = @a.zip.prepend("0")
@a.zip = new_zip
@a.save!
@a.reload
@z = Account.find @a.id
expect(@z.zip).to eq('0299')
end
it 'TEST B' do
@a= create(:account, zip: '299')
@a.zip = "0299"
@a.save!
@a.reload
@z = Account.find @a.id
expect(@z.zip).to eq('0299')
end
最佳答案
所以我认为您被 insert
和 prepend
都就地修改字符串这一事实所困扰:
1.9.3-p194 :001 > s = "a"
=> "a"
1.9.3-p194 :002 > s.prepend "b"
=> "ba"
1.9.3-p194 :003 > s
=> "ba"
1.9.3-p194 :004 > s.insert 0, "c"
=> "cba"
1.9.3-p194 :005 > s
=> "cba"
当您这样做时,Rails 不知道您已经更改了字符串内容。即使分配 @a.zip = new_zip
也无济于事,因为 @a.zip
和 new_zip
仍然是同一个对象,如果 rails在 zip=
方法中比较它们,它们看起来是相同的。因此 Rails 认为属性没有改变。这就是为什么在您的控制台 session 中,当您说 a.save!
时没有发出 UPDATE
。 Rails 没有意识到该属性是脏的。
您可以通过调用 s.zip_will_change!
来解决这个问题。或者对新字符串进行赋值,例如 s.zip = "0#{s.zip}"
。
关于ruby-on-rails - 在 postgres/active record 中保存字符串时保持前导零,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35298930/