Миграции в Rails Engine? - PullRequest
       7

Миграции в Rails Engine?

37 голосов
/ 24 декабря 2010

У меня есть несколько приложений rails, говорящих с одним и тем же бэкэндом, и я хочу, чтобы они поделились некоторыми миграциями.
Я установил рельсовый движок (с enginex), я могу поделиться чем угодно (контроллерами, представлениями, моделями, ...), но без миграций. Я не могу заставить это работать!

Я попытался создать файл db / migrate / my_migration.rb, но в моем основном приложении, если я это сделаю:

  rake db:migrate

Он их не загружает.

После некоторого поиска в Google, кажется, была какая-то недавняя работа по этому вопросу, и кажется, что этот был объединен с rails master. Я с рельсами 3.0.3 вы видите какой-нибудь способ заставить эту работу?

Спасибо!

Ответы [ 6 ]

37 голосов
/ 07 ноября 2011

В rails 3.1 вы можете сделать это с помощью этой команды, указав имя вашего двигателя example:

# Note that you append _engine to the name
rake example_engine:install:migrations
32 голосов
/ 18 января 2011

Что я делаю, так это добавлю InstallGenerator, который добавит миграции на сам сайт Rails. Это поведение не совсем то, что вы упомянули, но сейчас, для меня, это достаточно хорошо.

Небольшая инструкция:

Сначала создайте папку lib\generators\<your-gem-name>\install и внутри этой папки создайте файл с именем install_generator.rb со следующим кодом:

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

и внутри lib/generators/<your-gem-name>/install/templates добавьте два файла, содержащие миграции, например, возьмите тот, названный 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

Затем, когда ваш драгоценный камень будет добавлен в какое-то приложение, вы можете просто сделать

rails g <your_gem_name>:install

и это добавит миграции, а затем вы можете просто сделать rake db:migrate.

Надеюсь, это поможет.

23 голосов
/ 03 декабря 2011

В версии 3.1 вы можете обмениваться миграциями, не устанавливая их, изменив config / application.rb, чтобы сделать что-то вроде этого:

# Our migrations live exclusively w/in the Commons project
config.paths['db/migrate'] = Commons::Engine.paths['db/migrate'].existent
21 голосов
/ 23 августа 2011

По состоянию на Rails 3.1 выглядит так:

bundle exec rake railties:install:migrations

Если вы хотите копировать только с определенного Railtie, то:

bundle exec rake railties:install:migrations FROM=foo_engine

Обратите внимание, что имя, которое вы называете своим драгоценным камнем, называется плюс _engine. Так что, если гем "foo", то имя foo_engine.

17 голосов
/ 12 февраля 2014

Для рельсов 4 используйте:

   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

13 голосов
/ 26 июня 2012

Чтобы отказаться от ответа Леви, вы также можете сделать что-то подобное в файле вашего движка в самом движке, а не в приложении.

Так в 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

Редактировать: будьте осторожны, чтобы не испортить историю миграции людей после этого, убедитесь, что вы добавили новую миграцию, если требуется изменение, в противном случае вы можете заставить кого-то сделать некрасивые откаты.

...