Mic*_*Fin 6 postgresql activerecord ruby-on-rails ruby-on-rails-4 rails-activerecord
我有一个名为Users的表,其活动列为boolean。我很快将需要将该列的类型更改为字符串。我还需要将Active的所有列值从:true更改为“ active”,将:false更改为“ inactive”。
要更改列类型,我将在ROR迁移期间使用 将列类型从Date更改为DateTime。
class ChangeColumnTypeInUsers < ActiveRecord::Migration
def up
change_column :users, :active, :string
end
def down
change_column :users, :active, :boolean
end
end
Run Code Online (Sandbox Code Playgroud)
我将如何更新列值,以便类型更改不会破坏它?它将自动将:true转换为“ true”吗?
您可以使用ALTER TABLE的USING子句轻松地完成此操作:
可选
USING
子句指定如何从旧的值计算新的列值;如果省略,则默认转换与从旧数据类型到新数据类型的转换相同。
一个简单的SQL类型转换将使您剩下字符串'true'
,'false'
因此您确实想添加USING。我会绕开AR并手动完成:
connection.execute(%q(
alter table users
alter column active
type text
using case when active then 'active' else 'inactive' end
))
Run Code Online (Sandbox Code Playgroud)
对您来说重要的部分是最后的using case ...
部分。您可以change_column
通过诱使AR进行“正确的事情” 来将其与常见的AR-ish 东西结合使用:
class ChangeColumnTypeInUsers < ActiveRecord::Migration
def up
change_column :users, :active, "text using case when active then 'active' else 'inactive' end"
end
def down
change_column :users, :active, "boolean using active = 'active'"
end
end
Run Code Online (Sandbox Code Playgroud)
请注意,我使用的text
是列类型。Rails会使用varchar(255)
数据库里面,当你说:string
没有限制,因为它可以为所有字符串类型的存储这是PostgreSQL的漂亮毫无意义几乎相同的内部,在长度的限制char(n)
,并varchar(n)
实际上使它们比使用更昂贵text
。然后,只有时间:string
对PostgreSQL有意义,您才有理由包括一个特定的对象:limit
(然后,对长度进行约束的text
列CHECK
会更有意义,但是AR太愚蠢,无法了解诸如CHECK
约束之类的“高级”东西)。