Rails引擎中的迁移?

Mik*_*ike 37 ruby-on-rails rails-engines ruby-on-rails-3

我有多个rails应用程序与同一个后端交谈,我希望他们分享一些迁移.
我设置了一个rails引擎(带有enginex),我可以共享任何东西(控制器,视图,模型......)但没有迁移.我做不到!

我尝试创建一个文件db/migrate/my_migration.rb,但在我的主应用程序中,如果我这样做:

  rake db:migrate
Run Code Online (Sandbox Code Playgroud)

它不加载它们.

经过一番Google上搜寻它似乎有一些最近的工作在这,似乎已经合并轨主.我用rails 3.0.3你有没有办法让这个工作?

谢谢 !

小智 38

在rails 3.1中,您可以使用此命令执行此操作,并指出您的引擎名称是example:

# Note that you append _engine to the name
rake example_engine:install:migrations
Run Code Online (Sandbox Code Playgroud)

  • 很酷,谢谢Jais.只是一个小小的澄清:在Rails 3.1下,第一部分以"_engine"结尾.例如,如果您的引擎被称为"gogo",您将运行`rake gogo_engine:install:migrations`. (3认同)

nat*_*vda 32

我所做的是添加一个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
Run Code Online (Sandbox Code Playgroud)

并在里面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
Run Code Online (Sandbox Code Playgroud)

然后,当您的宝石添加到某个应用程序时,您可以这样做

rails g <your_gem_name>:install
Run Code Online (Sandbox Code Playgroud)

这将添加迁移,然后你就可以了rake db:migrate.

希望这可以帮助.

  • 这对于Rails 3.1来说不是必需的. (6认同)
  • 我很好奇你如何处理需要迁移更改的插件更新. (2认同)

Lev*_*evi 23

在3.1下,您可以通过更改config/application.rb来执行以下操作来共享迁移,而无需安装它们:

# Our migrations live exclusively w/in the Commons project
config.paths['db/migrate'] = Commons::Engine.paths['db/migrate'].existent
Run Code Online (Sandbox Code Playgroud)

  • 这在Rails 3.1.3中对我很有用.比其他答案更优选的方法.我尝试更进一步,将配置行直接添加到我的gem中的Engine类本身(在新的应用程序中安装gem时要少做一件事).我知道当我运行db:migrate时它会被读取,因为如果我有拼写错误就会抛出错误.但是,一旦拼写错误被修复,`rake db:migrate`就没有做任何事情. (5认同)

Eri*_*son 21

从Rails 3.1看起来解决方案是:

bundle exec rake railties:install:migrations
Run Code Online (Sandbox Code Playgroud)

如果您只想从特定的铁路复制,那么:

bundle exec rake railties:install:migrations FROM=foo_engine
Run Code Online (Sandbox Code Playgroud)

请注意,名称是宝石的名称加上_engine.因此,如果gem是"foo",则名称为foo_engine.


mon*_*ike 17

对于导轨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
Run Code Online (Sandbox Code Playgroud)

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

  • 你如何在引擎开发中处理这个问题,你需要在 `test/dummy` 应用程序的上下文中运行任务,其中 `app.root` 总是匹配 `root`?(另一位评论者在 Pivotal 帖子中提出了同样的问题,但没有得到答案。) (2认同)

rov*_*ver 13

要想了解Levi的答案,您也可以在实际引擎中的引擎文件中执行类似的操作,而不是应用程序.

所以在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
Run Code Online (Sandbox Code Playgroud)

编辑:小心但是在执行此操作后不要弄乱人员迁移历史记录,请确保在需要更改时添加新迁移,否则您可能会强迫某人执行一些丑陋的回滚.