{"id":22511109,"url":"https://github.com/rjayroach/all_your_migrations","last_synced_at":"2025-07-17T20:41:22.310Z","repository":{"id":21388363,"uuid":"24706069","full_name":"rjayroach/all_your_migrations","owner":"rjayroach","description":"Legacy Database Migrations for Rails","archived":false,"fork":false,"pushed_at":"2014-10-22T10:44:57.000Z","size":328,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-02-02T02:28:36.256Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rjayroach.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"MIT-LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2014-10-02T04:13:32.000Z","updated_at":"2014-10-02T04:13:56.000Z","dependencies_parsed_at":"2022-07-30T04:18:00.523Z","dependency_job_id":null,"html_url":"https://github.com/rjayroach/all_your_migrations","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rjayroach%2Fall_your_migrations","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rjayroach%2Fall_your_migrations/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rjayroach%2Fall_your_migrations/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rjayroach%2Fall_your_migrations/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rjayroach","download_url":"https://codeload.github.com/rjayroach/all_your_migrations/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245949553,"owners_count":20698916,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-12-07T02:08:47.391Z","updated_at":"2025-03-28T00:40:43.660Z","avatar_url":"https://github.com/rjayroach.png","language":"Ruby","readme":"# AllYourMigrations\n\n## About You\nYou are:\n* Developing a shiny new Rails app that will be working with (or replacing) a legacy application\n* Dealing with (avoiding, dreading, awake late at night, etc) writing migration code to convert the legacy database\n* Looking for something to give you:\n\n* straight forward query statements using A/R, but still want\n* best performance you can get by running raw SQL and\n* support for one off and periodic, e.g. daily, hourly, etc, migrations and\n* transparent support for joins against legacy DB\n\nThen:\n\nAll your migrations are belong to us!\n\n\n## About This Gem\nDocumentation\ninclude a sample rake file with big bang and daily migrations\n\ninclude a database.yml file example with legacy db confif\n\nin a separate repo:\na sample rails app with a new bd, a legacy db with crazy table names, legacy namespaced models, new models with the AYM code, rake files to migrate and seed data in the form of a sql dump. rake db:seed runs the dump back into legacy\n\n\n\n## Installation\n\nAdd this line to your application's Gemfile:\n\n    gem 'all_your_migrations'\n\nAnd then execute:\n\n    $ bundle\n\nOr install it yourself as:\n\n    $ gem install all_your_migrations\n\n## Usage\n\nSettings\nNOTE: AYM migration_options can be set at the global, model and/or migration (NOT action) levels; The more specific setting takes precedence\nNOTE: primary_key and legacy_tables can be set globally; run_after only makes sense at model level and below\n\n```ruby\n{:namespaces=\u003e[Legacy], :primary_key=\u003e:legacy_id, :legacy_tables=\u003enil, :run_after=\u003eMigrations::Merchant}\n\nLikely to set at Application level: namespaces, primary_key (legacy_tables is set automagically from namespaces value)\nLikely to be set at model level: primary_key, legacy_tables, run_after\nLikely to be set at migration level: primary_key, legacy_tables, run_after\nLikely to be set at action level: primary_key, legacy_tables\n\n```\n\n\n### Additional Steps for a Legacy Database\n\nconfig/environements/development.rb:\n```ruby\nconfig.eager_load = true\n```\n\nconfig/application.rb:\n```ruby\nconfig.to_prepare do\n  Rails.application.config.migration_options = {namespaces: Legacy, primary_key: :legacy_id}\nend\n```\n\n#### Configure access to the legacy database\n```ruby\nlegacy:\n  \u003c\u003c: *default\n  database: legacy_db\n  username: \u003c%= ENV[\"DB_USERNAME\"] %\u003e\n  password: \u003c%= ENV[\"DB_PASSWORD\"] %\u003e\n  host: \u003c%= ENV[\"DB_HOST\"] %\u003e\n```\n\n#### Model the legacy tables\nWe suggest creating a gem for the legacy models\n\n```ruby\nmodule Legacy\n  class Vendor \u003c ActiveRecord::Base\n    establish_connection :legacy\n    self.table_name = \"vendor\"\n    self.primary_key = \"vendor_id\"\n    belongs_to :city\n    has_many :vendor_addresses\n  end\nend\n```\n\n* Create an initializer for this gem (legacy_namespace, legacy_databse, legacy_tables)\n\n#### Define the migrations inside the model:\n\nAssuming you have two models, Vendor and Merchant. Vendor is the legacy model in the legacy database\n\nNextThing.migrations(:big_bang).execute!\n\n```ruby\nclass Merchant \u003c ActiveRecord::Base\n  include AllYourMigrations::Migratable\n  belongs_to :legacy, class_name: 'Legacy::Vendor'\n  migration_option_key: :legacy_id\n  belongs_to_migration :big_bang, actions: [:insert_new_merchants]\n\ndef insert_new_merchant\n  insert_into(self).values(columns).from(A/R query).key_on(:legacy_id).with_legacy_table_map(nil)\n  # insert_into, values and from are methods on Migration\nend\n\ndef update_place_code\n  update_into(self).from(A/R query).set(set string).where(where string)\n  # update_into, from, set and where are methods on Migration\nend\n\n\n  # Insert new records created since last import\n  def insert_new_merchants\n    insert_into(self).values(:legacy_id,\n                             :created_at,\n                             :updated_at,\n                             :name,\n                             :state,\n                             :logo)\n                     .from(Legacy::Vendor.where('vendor_id \u003e ?', last_migrated_id)\n                                         .select(:vendor_id,\n                                                 :create_date,\n                                                 :last_updated_date,\n                                                 :name,\n                                                 'IF(`vendor`.`active` = 1, 4, 5)',\n                                                 :vendor_logo)\n                     .link_by(:legacy_id)\n  end\nend\n```\n\n\n### Migrating\n\n#### Sample Migration Rakefile\nTo run from cli (for testing or to invoke from capistrano, etc) you can include tasks\nThe organization here is something we've refined over several migrations and works well for us\n\n\n```ruby\ndef to_boolean(str, default = false)\n  str.nil? ? default : str.eql?('true')\nend\n\n\nnamespace :aym do\n  task :migrate do\n    Rake::Task['aym:migrate:merchants'].invoke\n  end\n\n  namespace :migrate do\n    task :initialize =\u003e [:environment] do\n      @debug = to_boolean(ENV['debug'], false)\n      @dry_run = to_boolean(ENV['dry_run'], false)\n      @reset = to_boolean(ENV['reset'], false)\n    end\n\n    task :merchants =\u003e [:initialize] do\n      Merchant.truncate! if @reset\n      Merchant.migrate!\n    end\n  end\nend\n```\n\n#### Run the Migrations\n\n```bash\nrake aym:migrate:merchants\nrake aym:migrate:merchants reset=true\n```\n\n\n## Contributing\n\n1. Fork it ( https://github.com/rjayroach/all_your_migrations/fork )\n2. Create your feature branch (`git checkout -b my-new-feature`)\n3. Commit your changes (`git commit -am 'Add some feature'`)\n4. Push to the branch (`git push origin my-new-feature`)\n5. Create a new Pull Request\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frjayroach%2Fall_your_migrations","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frjayroach%2Fall_your_migrations","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frjayroach%2Fall_your_migrations/lists"}