Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generated migration is not Strong Migrations compatible #1755

Closed
thedumbtechguy opened this issue Mar 26, 2024 · 2 comments
Closed

Generated migration is not Strong Migrations compatible #1755

thedumbtechguy opened this issue Mar 26, 2024 · 2 comments

Comments

@thedumbtechguy
Copy link

thedumbtechguy commented Mar 26, 2024

Strong Migrations flags the generated migration as dangerous due to the out of band foreign key and index creation.

The generated migration looks like this

# frozen_string_literal: true

class CreateEventStoreEvents < ActiveRecord::Migration[7.1]
  def change
    create_table(:event_store_events_in_streams, id: :bigserial, force: false) do |t|
      t.string      :stream,      null: false
      t.integer     :position,    null: true
      t.references  :event,       null: false, type: :uuid, index: false
      t.datetime    :created_at,  null: false, type: :timestamp, precision: 6, index: true
    end
    add_index :event_store_events_in_streams, [:stream, :position], unique: true
    add_index :event_store_events_in_streams, [:stream, :event_id], unique: true
    add_index :event_store_events_in_streams, [:event_id]

    create_table(:event_store_events, id: :bigserial, force: false) do |t|
      t.references  :event,       null: false, type: :uuid, index: { unique: true }
      t.string      :event_type,  null: false, index: true
      t.jsonb      :metadata
      t.jsonb      :data, null: false
      t.datetime    :created_at,  null: false, type: :timestamp, precision: 6, index: true
      t.datetime    :valid_at,    null: true, type: :timestamp, precision: 6, index: true
    end

    add_foreign_key "event_store_events_in_streams", "event_store_events", column: "event_id", primary_key: "event_id"
  end
end

I modified mine to this to get it to work correctly.

# frozen_string_literal: true

class CreateEventStoreEvents < ActiveRecord::Migration[7.1]
  def change
    create_table(:event_store_events, id: :bigserial, force: false) do |t|
      t.references :event, null: false, type: :uuid, index: {unique: true}
      t.string :event_type, null: false, index: true
      t.jsonb :metadata
      t.jsonb :data, null: false
      t.datetime :created_at, null: false, type: :timestamp, precision: 6, index: true
      t.datetime :valid_at, null: true, type: :timestamp, precision: 6, index: true
    end

    create_table(:event_store_events_in_streams, id: :bigserial, force: false) do |t|
      t.string :stream, null: false
      t.integer :position, null: true
      t.references :event, null: false, type: :uuid, index: false, foreign_key: {to_table: :event_store_events, primary_key: :event_id}
      t.datetime :created_at, null: false, type: :timestamp, precision: 6, index: true

      t.index [:stream, :position], unique: true
      t.index [:stream, :event_id], unique: true
      t.index [:event_id]
    end
  end
end

My schema.rb looks this

  create_table "event_store_events", force: :cascade do |t|
    t.uuid "event_id", null: false
    t.string "event_type", null: false
    t.binary "metadata"
    t.binary "data", null: false
    t.datetime "created_at", null: false
    t.datetime "valid_at"
    t.index ["created_at"], name: "index_event_store_events_on_created_at"
    t.index ["event_id"], name: "index_event_store_events_on_event_id", unique: true
    t.index ["event_type"], name: "index_event_store_events_on_event_type"
    t.index ["valid_at"], name: "index_event_store_events_on_valid_at"
  end

  create_table "event_store_events_in_streams", force: :cascade do |t|
    t.string "stream", null: false
    t.integer "position"
    t.uuid "event_id", null: false
    t.datetime "created_at", null: false
    t.index ["created_at"], name: "index_event_store_events_in_streams_on_created_at"
    t.index ["event_id"], name: "index_event_store_events_in_streams_on_event_id"
    t.index ["stream", "event_id"], name: "index_event_store_events_in_streams_on_stream_and_event_id", unique: true
    t.index ["stream", "position"], name: "index_event_store_events_in_streams_on_stream_and_position", unique: true
  end
  
  add_foreign_key "event_store_events_in_streams", "event_store_events", column: "event_id", primary_key: "event_id"
@thedumbtechguy
Copy link
Author

Another thing I did was use gin indexes. But that may not fit the library.

image

@mostlyobvious
Copy link
Member

mostlyobvious commented Mar 29, 2024

Thank you for pointing this out! Next RES release should include migration templates compatible with strong_migrations (#1759)

As for the GIN indexes, I've extracted it to a separate issue — it has been on the roadmap already but a little more visibility won't hurt.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants