奇怪的Rails迁移/ schema.rb问题

时间:2017-04-23 07:57:55

标签: ruby-on-rails database-schema rails-migrations

前段时间我运行了以下迁移:

class CreatePipelineSpecs < ActiveRecord::Migration
  def change
    create_table :pipeline_specs do |t|
      t.integer :id_no
      t.string :od
      t.string :wt
      t.string :material
      t.string :spec_type
      t.string :spec_grade
      t.string :mop
      t.string :stress_level
      t.string :joints
      t.text :notes
      t.string :ip
      t.references :pipeline, index: true, foreign_key: false

      t.timestamps null: false
    end
    add_index :pipeline_specs, :id_no
  end
end

我不确定现在发生了什么,但每次运行rake db:migrate时,scheme.rb文件都会更新:

  create_table "pipeline_specs", force: :cascade do |t|
    t.integer  "id_no"
    t.string   "od"
    t.string   "wt"
    t.string   "material"
    t.string   "spec_type"
    t.string   "spec_grade"
    t.string   "mop"
    t.string   "stress_level"
    t.string   "joints"
    t.text     "notes"
    t.string   "ip"
    t.integer  "pipelines_id"
    t.datetime "created_at",   null: false
    t.datetime "updated_at",   null: false
  end

  add_index "pipeline_specs", ["id_no"], name: "index_pipeline_specs_on_id_no", using: :btree
  add_index "pipeline_specs", ["pipelines_id"], name: "index_pipeline_specs_on_pipelines_id", using: :btree

请注意复数 pipelines_id 。实际的数据库表(开发,生产等)都是 pipeline_id ,这是正确的,因为参考表是Pipeline。所以我添加了一个新的不相关的迁移,schema.rb得到了更新,这些在我更改后再次变回复数。如果我在运行测试时忘记更改它们,那么当错误的模式加载到测试环境中时,一切都会中断。

我在这里不知所措。我在这里遗漏了一些明显的东西,或者是否有一些隐藏的迁移模式表等。

唯一的想法是,当我进行原始迁移时,我使用了pipelines:references vs pipeline:references,然后解决了我的错误,然后在提交和部署之前清理了迁移。< / p>

这里有任何想法,为什么会发生这种情况以及如何一劳永逸地解决这个问题?

更新

以下是我的三个相关模型:

irb(main):031:0> Pipeline
=> Pipeline(id: integer, licence: string, company: string, company_id: integer, ba_code: string, substance_code: string, substance: string, h2s: string, partial_pressure: string, notes: text, created_at: datetime, updated_at: datetime, slug: string)
irb(main):032:0> PipelineSpec
=> PipelineSpec(id: integer, id_no: integer, od: string, wt: string, material: string, spec_type: string, spec_grade: string, mop: string, stress_level: string, joints: string, notes: text, ip: string, pipeline_id: integer, created_at: datetime, updated_at: datetime, slug: string)
irb(main):033:0> PipelineSegment
=> PipelineSegment(id: integer, line: integer, lsd_from: integer, sec_from: integer, twp_from: integer, rge_from: integer, m_from: integer, fc_from: string, lsd_to: integer, sec_to: integer, twp_to: integer, rge_to: integer, m_to: integer, fc_to: string, length: string, aasm_state: string, state_comment: string, state_user_id: integer, aasm_date: datetime, env: string, volume: string, notes: text, pipeline_id: integer, pipeline_spec_id: integer, created_at: datetime, updated_at: datetime, slug: string)

Pipeline has_many PipelineSpecPipelineSegmentPipelineSegment has_one PipelineSpec

更新2

检查我的测试环境架构 - 没关系。 Ran rake db:migrate并再次更新schema.rb。再次运行测试并获得:

ActiveRecord::StatementInvalid:         ActiveRecord::StatementInvalid: PG::UndefinedColumn: ERROR:  column "pipeline_id" of relation "pipeline_specs" does not exist
        LINE 1: ..., "mop", "stress_level", "joints", "notes", "ip", "pipeline_...
                                                                     ^
        : INSERT INTO "pipeline_specs" ("id", "id_no", "od", "wt", "material", "spec_type", "spec_grade", "mop", "stress_level", "joints", "notes", "ip", "pipeline_id", "created_at", "updated_at") VALUES (1, 1, '88.9', '3.18', 'S', 'Z245.1', '359 2', '9930', '25', 'W', 'MyText', 'U', 1, '2017-04-24 03:47:26', '2017-04-24 03:47:26')

因为灯具试图加载到刚刚在测试时加载的不正确的测试架构。

3 个答案:

答案 0 :(得分:1)

每次迁移后,架构都是 how Pandas handles indexing数据库。所以我想pipelines_id必定确实存在于db中的某个地方,或者至少Rails必须认为它存在于db中。我会采取以下措施来缩小问题范围:

  • 运行rake db:schema:dump SCHEMA=myschema.rb - 这将手动生成一个命名不同的模式文件。这与迁移后运行的rake任务相同。我希望新架构也会包含复数pipelines_id列。

  • 然后我会查看log/development.log(或者您遇到问题的任何环境)。您应该看到SELECT schema_migrations.* FROM schema_migrations和一堆进一步的查询,以显示数据库中每个表的结构。找到处理pipeline_specs表的查询并在数据库控制台中手动运行它以查看您精确获取的内容。我的期望是你要么:

    • 在那里也看到复数pipelines_ids - 这将证明该列确实存在于db
    • 与否 - 在这种情况下,我会重新启动我在rails中可以做的一切,以确保在任何地方都没有涉及缓存 - 特别是我用spring stop重新启动spring。另外,我会检查(不知道Postgres是否可以肯定地告诉)Postgres方面是否有任何缓存。然后我再试一次。

答案 1 :(得分:0)

我认为,因为您删除的迁移不在测试环境中运行,请尝试通过以下方式重置测试数据库:

RAILS_ENV=test rake db:migrate:reset

答案 2 :(得分:0)

尝试在模型foregein_key中指定PipelineSpecpipelines_id

class PipelineSpec < ActiveRecord::Base
  belongs_to :pipeline, foreign_key: :pipelines_id
end