Reputation: 5872
I've just been trying to figure out some ways to optimize my MySQL database, but I'm having a bit of an issue with indexing here.
As opposed to stacking up a bunch of migration files (since I'm not really managing much data yet), I'm simply "going back" and editing migration files periodically to include columns, etc. Not sure if this is best practice, but I figured it'd be easier to avoid ending up with 100 migration files adding small things.
Anyways, I'm trying to add an index to one of the columns in a migration file, but I can't seem to get it to work (it's not showing up in the schema file after rolling back and migrating again).
class CreateVuln < ActiveRecord::Migration
def change
create_table :vuln do |t|
t.integer :node_id
t.string :node_identifier
t.string :vuln_finding_identifier
t.timestamps null: false
end
add_index :vuln, :node_identifier
end
end
But when I go to schema.rb, here's what it looks like:
create_table "vuln", force: :cascade do |t|
t.integer "node_id", limit: 4
t.string "node_identifier", limit: 255
t.string "vuln_finding_identifier", limit: 255
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
Can someone tell me what I'm missing here? If I add a new migration by running rails g migration AddIndexToVuln node_identifier:string:index
then I can see that the schema.rb file gets updated properly. schema.rb then adds this line: add_index "vuln", ["node_identifier"], name: "index_vuln_on_node_identifier", using: :btree
So as opposed to creating a new migration file, I'm just wondering if I can just roll back my database and make the changes in the existing migration file for that table.
Upvotes: 0
Views: 385
Reputation: 5633
It's important to first understand what's going on with your migration.
So, Rails uses timestamps to track the changes in your migration, so when you run rake db:migrate, Rails would first look at the schema.rb
to check the current state of the your db. You would have seen this kind of line in your schema file: ActiveRecord::Schema.define(version: 20160625234411) do
, all migrations are versioned by a timestamp in this fashion.
Therefore, it would only run any new migration, i.e whose timestamp is greater than that on the schema file.
So, that's reason you should actually generate a new migration if you want to change the state of your db, otherwise, you would have to keep doing rake db:[drop|reset]
etc everytime to get things working.
Upvotes: 1
Reputation: 11570
I don't see anything wrong with your migration so the first thing to check is whether rake db:rollback
actually succeeds. If you ran the rollback after adding the add_index
line then the rollback should fail since Rails will attempt a remove_index
on a non-existent index. If the rollback fails, the fix is simple. Comment out the add_index
line and run rake db:rollback
, uncomment the line and then run rake db:migrate
.
If you're in the early stages of development and truly don't care about the data, you can run rake db:reset
which will drop the db and rebuild starting with the first migration.
All that being said, there is absolutely nothing wrong with creating new migrations (no matter how small) to modify the schema - this is their intended purpose. Sooner or later you will get to a point where rolling back and modifying migrations just won't scale so just embrace the approach from the get-go.
Upvotes: 1