【问题标题】:rake test not copying development postgres db with sequencesrake 测试不使用序列复制开发 postgres db
【发布时间】:2010-05-31 09:01:47
【问题描述】:

我正在尝试在 postgresql 上开发一个 Rails 应用程序,使用序列来增加字段,而不是基于 validates_uniqueness_of 的默认 ruby​​ 方法。

事实证明,这具有挑战性,原因有很多: 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。很明显,rails 在那之后又做了一些事情来压制它。

关于如何解决此问题的任何建议?

谢谢 罗伯特

【问题讨论】:

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


    【解决方案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
    
    ###########################################################################
    ###########################################################################
    

    【讨论】:

      【解决方案2】:

      我偶然发现了同样的问题。对于未来的访客

      基本上把它放在你的 config/environments/development.rb 中并运行你的测试。

          config.active_record.schema_format = :sql
      

      更多信息 - https://rails.lighthouseapp.com/projects/8994/tickets/5849-rails3-rake-task-dbtestprepare-no-longer-handles-stored-procedures

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-04-13
        • 2012-12-11
        • 2014-10-02
        • 1970-01-01
        • 1970-01-01
        • 2017-07-21
        相关资源
        最近更新 更多