Migrations in Rails Engine?

前端 未结 6 1601
暗喜
暗喜 2020-12-12 14:48

I have multiple rails applications talking to the same backend and I\'d like them to share some migrations.
I setup a rails engine (with enginex), I can share anything (

相关标签:
6条回答
  • 2020-12-12 14:51

    As of Rails 3.1 looks like the solution is:

    bundle exec rake railties:install:migrations
    

    If you only want to copy from a specific railtie then:

    bundle exec rake railties:install:migrations FROM=foo_engine
    

    Note the name is whatever you gem is named plus _engine. So if the gem is "foo" then the name is foo_engine.

    0 讨论(0)
  • 2020-12-12 14:56

    Under 3.1, you can share migrations, without installing them, by altering config/application.rb to do something like this:

    # Our migrations live exclusively w/in the Commons project
    config.paths['db/migrate'] = Commons::Engine.paths['db/migrate'].existent
    
    0 讨论(0)
  • 2020-12-12 15:01

    For rails 4 use:

       initializer :append_migrations do |app|
          unless app.root.to_s.match root.to_s
            config.paths["db/migrate"].expanded.each do |expanded_path|
              app.config.paths["db/migrate"] << expanded_path
            end
          end
        end
    

    https://content.pivotal.io/blog/leave-your-migrations-in-your-rails-engines

    0 讨论(0)
  • 2020-12-12 15:02

    In rails 3.1, you can do it using this command, give that your engine name is example:

    # Note that you append _engine to the name
    rake example_engine:install:migrations
    
    0 讨论(0)
  • 2020-12-12 15:07

    To go off of Levi's answer you could also do something like this in your engine file in the actually engine, instead of the application.

    So in lib/commons/engine.rb

    module Commons
      class Engine < Rails::Engine
        initializer "commons.load_app_instance_data" do |app|
          Commons.setup do |config|
            config.app_root = app.root
          end
          app.class.configure do 
            #Pull in all the migrations from Commons to the application
            config.paths['db/migrate'] += Commons::Engine.paths['db/migrate'].existent
          end
        end
        initializer "commons.load_static_assets" do |app|
          app.middleware.use ::ActionDispatch::Static, "#{root}/public"
        end
      end
    end
    

    Edit: Be careful though to not mess up people migration history after doing this, make sure you add a new migration if a change is needed, otherwise you might force someone to do some ugly rollbacks.

    0 讨论(0)
  • 2020-12-12 15:15

    What i do, is add an InstallGenerator that will add the migrations to the Rails site itself. It has not quite the same behavior as the one you mentioned, but for now, for me, it is good enough.

    A small how-to:

    First, create the folder lib\generators\<your-gem-name>\install and inside that folder create a file called install_generator.rb with the following code:

    require 'rails/generators/migration'
    
    module YourGemName
      module Generators
        class InstallGenerator < ::Rails::Generators::Base
          include Rails::Generators::Migration
          source_root File.expand_path('../templates', __FILE__)
          desc "add the migrations"
    
          def self.next_migration_number(path)
            unless @prev_migration_nr
              @prev_migration_nr = Time.now.utc.strftime("%Y%m%d%H%M%S").to_i
            else
              @prev_migration_nr += 1
            end
            @prev_migration_nr.to_s
          end
    
          def copy_migrations
            migration_template "create_something.rb", "db/migrate/create_something.rb"
            migration_template "create_something_else.rb", "db/migrate/create_something_else.rb"
          end
        end
      end
    end
    

    and inside the lib/generators/<your-gem-name>/install/templates add your two files containing the migrations, e.g. take the one named create_something.rb :

    class CreateAbilities < ActiveRecord::Migration
      def self.up
        create_table :abilities do |t|
          t.string  :name
          t.string  :description
          t.boolean :needs_extent      
          t.timestamps
        end
      end
    
      def self.down
        drop_table :abilities
      end
    end
    

    Then, when your gem is added to some app, you can just do

    rails g <your_gem_name>:install
    

    and that will add the migrations, and then you can just do rake db:migrate.

    Hope this helps.

    0 讨论(0)
提交回复
热议问题