6

私はSaaSモデルのアプリケーションを書いています。私のアプリケーション データベースは、次の 2 つのロジック部分で構成されています。

  • アプリケーション テーブル - ユーザー、ロールなど
  • アプリケーションインスタンスごとに異なるユーザー定義テーブル (UI レベルから生成できます)

すべてのテーブルは rails migrations メカニズムによって作成されます。

ユーザー定義のテーブルを別のディレクトリに置きたい:

  • db/migrations - アプリケーション テーブル
  • db/migrations/custom - ユーザーが生成したテーブル

そのため、db/migrations/custom で svn:ignore を実行できます。クライアント サーバーでアプリを更新すると、アプリケーション テーブルの移行のみが更新されます。

レールでこれを達成する方法はありますか?

4

5 に答える 5

7

タスクrake db:migrateには、移行へのハードコードされたパスがあります。ただし、独自の rake タスクを作成できます。たとえばlib/tasks/custom_db_migrate.rake、次の内容で作成します。

namespace :db do
  task :custom_migrate => :environment do
    ActiveRecord::Migration.verbose = ENV["VERBOSE"] ? ENV["VERBOSE"] == "true" : true
    ActiveRecord::Migrator.migrate("db/migrate/custom", ENV["VERSION"] ? ENV["VERSION"].to_i : nil)
    Rake::Task["db:schema:dump"].invoke if ActiveRecord::Base.schema_format == :ruby
  end
end

rake db:custom_migrateにあるマイグレーションを実行できるようになりましたdb/migrate/custom。ただし、デフォルト パスからの移行は使用されません。

ActiveRecord 移行のソース コードを読みたいと思うかもしれません。

于 2011-01-08T21:51:15.113 に答える
4

Sinatra を使用して独自の rake タスクを作成している場合は、次のことができます。

require './app'
require 'sinatra/activerecord/rake'

ActiveRecord::Migrator.migrations_paths = 'your/path/goes/here'

を実行するrake -Tと、db 名前空間が取得されます。

rake db:create_migration  # create an ActiveRecord migration
rake db:migrate           # migrate the database (use version with VERSION=n)
rake db:rollback          # roll back the migration (use steps with STEP=n)
于 2013-04-04T23:59:06.920 に答える
2

@Vasily さん、ご返信ありがとうございます。それを読んで、stackoverflowからさらにいくつかの質問をした後、私はこの解決策を思いつきました:

私は独自のジェネレーターを作成してユーザー テーブルを作成するので、Rails::Generators::Migration を含めたので、次のように next_migration_number メソッドをオーバーライドできます。

def self.next_migration_number(dirname)
 if ActiveRecord::Base.timestamped_migrations
   Time.now.utc.strftime("custom/%Y%m%d%H%M%S")
 else
   "custom/%.3d" % (current_migration_number(dirname) + 1)
 end
end

これで、ユーザーによって生成されたすべての移行が db/migrations/custom ディレクトリに作成されます。

次に、db/migrations/custom ディレクトリからすべての移行を実行する通常の rails migration を作成しました。

class ExecuteCustomMigrations < ActiveRecord::Migration
   MIGRATIONS_PATH='db/migrate/custom'
   def self.up
     Dir["#{MIGRATIONS_PATH}/[0-9]*_*.rb"].
     sort.map{|filename|require filename}.flatten.
     each{|class_name| const_get(class_name).up}
   end

   def self.down
     Dir["#{MIGRATIONS_PATH}/[0-9]*_*.rb"].sort.reverse.
     map{|filename|require filename}.flatten.
     each{|class_name| const_get(class_name).down}
   end
end

ユーザーがカスタム テーブルを作成した後、次のコードでこの移行を呼び出します。

Rake::Task["db:migrate:redo"].execute("VERSION=20110108213453")
于 2011-01-09T10:18:26.643 に答える