Casecommons / with_model

Dynamically build an Active Record model (with table) within a test context
http://www.casebook.net
MIT License
167 stars 18 forks source link

Generated index names on midsize model names are excessively large under AR5+ #27

Closed arubis closed 6 years ago

arubis commented 6 years ago

We've been migrating a project that uses with_mocks in its specs to Rails 5 from 4.2, and are finding that the autogenerated names for indices are now frequently longer than the character limit for our underlying database (PG9.6). This may not be a bug in with_mocks per se, if it's just a result of changes upstream in ActiveRecord, but documenting this behavior would be helpful for future users.

Manually specifying a shorter index name addresses the issue for now.

Breaking example:

require "rails_helper"

describe "index issue" do
  with_model :MidsizeNameChild do
    table do |t|
      t.belongs_to :midsize_name_parent
    end

    model do
      belongs_to :midsize_name_parent
    end
  end

  with_model :MidsizeNameParent do
    model do
      has_many :midsize_name_children
    end
  end

  let(:instance) { MidsizeNameParent.create }

  describe "try to instantiate" do
    it "is an example" do
      instance
    end
  end
end

Produces: Index name 'index_with_model_midsize_name_children_39923_70337190696860_on_midsize_name_parent_id' on table 'with_model_midsize_name_children_39923_70337190696860' is too long; the limit is 63 characters (though UUID will vary)

Working example:

require "rails_helper"

describe "index issue" do
  with_model :MidsizeNameChild do
    table do |t|
      t.belongs_to :midsize_name_parent,
                   index: { name: "shorter_index_name" }
    end

    model do
      belongs_to :midsize_name_parent
    end
  end

  with_model :MidsizeNameParent do
    model do
      has_many :midsize_name_children
    end
  end

  let(:instance) { MidsizeNameParent.create }

  describe "try to instantiate" do
    it "is an example" do
      instance
    end
  end
end

(passes)

amarshall commented 6 years ago

We say in the readme:

The table block works just like a migration.

Which holds true. There’s nothing happening here that wouldn’t happen in a “regular” migration. The first search result for “activerecord index too long” also has the correct solution. I’d like to avoid going down the road of documenting ActiveRecord’s behavior here rather than delegating to its own documentation. And I don’t want to try and work around it because we don’t know what the length constraint is (it’s database-specific), and I’d rather keep the table block a vanilla create_table block.

FWIW, you could also (I think) provide index: false, since the index probably doesn’t get used anyway as I’d expect most with_model tables to have few records in them.

That said, I’ve clarified the documentation a bit in 583edba0967fbe9513c1c7055514eea6f7dbb582.