我正在尝试使用序列来增加字段而不是基于validates_uniqueness_of的默认ruby方法在postgresql上开发rails应用程序。
由于多种原因,这已经证明具有挑战性: 1.这是现有表的迁移,而不是新表或列的迁移 2.使用参数:default => “nextval('seq')”无效,因为它试图在括号中设置它 3.最终让迁移分两步进行:
change_column :work_commencement_orders, :wco_number_suffix, :integer, :null => false#, :options => "set default nextval('wco_number_suffix_seq')"
execute %{
ALTER TABLE work_commencement_orders ALTER COLUMN wco_number_suffix SET DEFAULT nextval('wco_number_suffix_seq');
}
现在,这似乎在开发数据库中完成了正确的操作,架构如下所示:
wco_number_suffix | integer | not null default nextval('wco_number_suffix_seq'::regclass)
然而,测试失败了
PGError: ERROR: null value in column "wco_number_suffix" violates not-null constraint
: INSERT INTO "work_commencement_orders" ("expense_account_id", "created_at",
"process_id", "vo2_issued_on", "wco_template", "updated_at", "notes", "process_type",
"vo_number", "vo_issued_on", "vo2_number", "wco_type_id", "created_by",
"contractor_id", "old_wco_type", "master_wco_number", "deadline", "updated_by",
"detail", "elective_id", "authorization_batch_id", "delivery_lat", "delivery_long",
"operational", "state", "issued_on", "delivery_detail") VALUES(226, '2010-05-31
07:02:16.764215', 728, NULL, E'Default', '2010-05-31 07:02:16.764215', NULL,
E'Procurement::Process', NULL, NULL, NULL, 226, NULL, 276, NULL, E'MWCO-213',
'2010-06-14 07:02:16.756952', NULL, E'Name 4597', 220, NULL, NULL, NULL, 'f',
E'pending', NULL, E'728 Test Road; Test Town; 1234; Test Land') RETURNING "id"
检查测试数据库的模式时可以找到解释:
wco_number_suffix | integer | not null
那么默认情况发生了什么?
我尝试添加
task:
template: smmt_ops_development
到database.yml文件,它具有发布
的效果create database smmt_ops_test template = "smmt_ops_development" encoding = 'utf8'
我已经验证过,如果我发出这个,那么它实际上会复制默认的nextval。所以很明显铁路公司正在采取措施再次压制它。
有关如何解决此问题的任何建议吗?
由于 罗伯特
答案 0 :(得分:1)
我没有解决问题,但为work_commencement_orders模型开发了以下解决方法,以使测试能够运行。
###########################################################################
###########################################################################
# NOTE this is purely for test, it should have no effect on development or production
# as the field will be marked readonly and prevented from being written to the db so that
# it picks up a default value from its sequence.
public
def before_validation
if wco_number_suffix.blank?
maximum = WorkCommencementOrder::Entity.maximum(:wco_number_suffix)
maximum ||= 0
self.wco_number_suffix = maximum + 1
end
end
private
def test?
@is_test ||= (ENV['RAILS_ENV'] == 'test')
end
# Override default behaviour so that when not in test environment it does not try
# to write readonly attributes during create but instead allows them to be initialised
# by default value.
def attributes_with_quotes(include_primary_key = true, include_readonly_attributes = test?, attribute_names = @attributes.keys)
super(include_primary_key, include_readonly_attributes, attribute_names)
end
###########################################################################
###########################################################################
答案 1 :(得分:0)
我偶然发现了同样的问题。对于未来的访客
基本上将它放在config / environments / development.rb中并运行测试。
config.active_record.schema_format = :sql