5

Background

We engineer database models and application models separately (RDMBS architects vs OOP engineers). From what I've seen regarding Rails versus domain/key normal form, Rails migrations cannot easily duplicate all the features of a well-designed enterprise RDBMS (if at all) so we don't migrate and instead use other tools to build databases (nevermind the problem of object-relational impedance mismatch). Data integrity and DB performance are too valuable to us to risk RDBMS model changes by any developer.

Question

For whatever reason, we now have a Rails app that has made damaging DB changes through migrations. How do I cleanly disable this feature in an existing Rails application?

I have my theories but I want to know what the world thinks.

juanitogan
  • 1,698
  • 1
  • 22
  • 37
  • 2
    Always best to share your theories and show what you've tried in a question. – Brian Jul 16 '14 at 16:07
  • If you use capistrano for deployment, I bet you could just configure it to skip the `db:migrate` rake task. Not sure about other deployment tools. – Brian Jul 16 '14 at 16:14
  • 2
    You could look into something like [this](http://stackoverflow.com/questions/8112074/overriding-rails-default-rake-tasks) and just overwrite all the database rake tasks to do nothing - or display a message "Naughty developer" maybe? I don't think there is actually anyway to disable them via a configuration option – j-dexx Jul 16 '14 at 16:16
  • Agreed, just write your own tasks, or create a migration template that allows either nothing, or a subset of stuff you deem "ok"; see http://stackoverflow.com/q/5202008/438992. – Dave Newton Jul 16 '14 at 16:37
  • @Brian. Yes, using Capistrano but was hoping for something even lower level than cap or rake. I believe we can modify one of the dev databases even without a cap deployment and I would like to avoid that as well. I was thinking more along the lines of replacing `require 'rails/all'` with an itemized list. Removing migrate from the cap task would be a good second layer of enforcement. Another option is to create two DB users: one for DB work, and one for Rails with less rights. Not sure how that will go over but probably the smartest route. Would still like to hobble Rails though. – juanitogan Jul 21 '14 at 21:21
  • You probably could work that out, I'd expect that list to get long though :-). This is essentially what the rails-api project does to slim down the dependencies: https://github.com/rails-api/rails-api/blob/master/lib/rails-api/application.rb – Brian Jul 22 '14 at 16:34
  • Or maybe something similar to this: http://stackoverflow.com/questions/8527459/using-datamapper-with-existing-rails-application – juanitogan Jul 22 '14 at 19:09

2 Answers2

7

This came up again when testing finally came to the front. Thus, I took deeper look and came up with the following thanks, in part, to the comments left on the question. This removes all rake DB capabilities and tests still run fine. (In case anyone is wondering, we clone the test DB from elsewhere when we need to refresh it.)

Add this to the Rakefile:

# Disable DB migrations, DB test preparing, etc.
Rake::Task.tasks.each do |t|
    if t.name[0,3] == "db:"
        t.clear
        t.add_description("!!! Disabled in favor of enterprise design at Acme.")
    end
end

Comment out all the fixtures in test/test_helper.rb:

#fixtures :all
juanitogan
  • 1,698
  • 1
  • 22
  • 37
5

In juanitogan's answer, we disable all db tasks. In my case I still wanted to be able to run db:schema:load. Here the slightly modified code for the Rakefile:

# Disable migrations
Rake::Task.tasks.each do |t|
  if t.name.start_with?("db:migrate")
    t.clear
    t.add_description("Disabled; Load the data model via db:schema:load.")
    t.actions << proc { puts "Migrations ignored. That's ok. Please see README."}
  end
end

When creating models, you can append the --no-migration option like so: rails g model abc --no-migration

Motine
  • 1,638
  • 18
  • 18
  • Do you mean to allow `db:schema:load` ? This will apply schema.rb to the current DB env and destroy all data. I think you mean to allow `db:schema:dump`, which creates a schema.rb that matches the database. You would still want to prevent `db:schema:load` though, not just migrate tasks. – Ryan Smith Apr 02 '17 at 17:02
  • actually, I meant `db:schema:load`, because I have a prescribed schema and want to load it. – Motine Apr 04 '17 at 06:15