2015-12-22 30 views
9

Ich suche, alle meine geteilten Modelle zu einer Maschine zu bewegen, die in jeder meiner Mikro-Anwendungen enthalten sein kann.Wie laden Sie mehrere Schemas in eine Rails-Engine oder App?

  • Modelldateien
  • Schema-Dateien
  • Migrationen (wir folgen Pivotal Labs' pattern, dies ist nicht das Problem):

    Dieser Motor sollte ein Modell Schicht für alle unsere Legacy-Daten, einschließlich liefern

Modelldateien werden automatisch eingepatcht, das ist in Ordnung.

Schema-Dateien in mit Nikolay Strum's db.rake Affen gepatcht werden:

namespace :db do 
    namespace :schema do 
    # desc 'Dump additional database schema' 
    task :dump => [:environment, :load_config] do 
     filename = "#{Rails.root}/db/foo_schema.rb" 
     File.open(filename, 'w:utf-8') do |file| 
     ActiveRecord::Base.establish_connection("foo_#{Rails.env}") 
     ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, file) 
     end 
    end 
    end 

    namespace :test do 
    # desc 'Purge and load foo_test schema' 
    task :load_schema do 
     # like db:test:purge 
     abcs = ActiveRecord::Base.configurations 
     ActiveRecord::Base.connection.recreate_database(abcs['foo_test']['database'], mysql_creation_options(abcs['foo_test'])) 
     # like db:test:load_schema 
     ActiveRecord::Base.establish_connection('foo_test') 
     ActiveRecord::Schema.verbose = false 
     load("#{Rails.root}/db/foo_schema.rb") 
    end 
    end 
end 

Wir brauchen rake db:create und rake db:schema:load zu arbeiten,

Die db.rake Patches betreffen nur db:schema:dump und db:test:load_schema (Teil tests_prepare, gehe ich davon aus) . Ich habe versucht, sie in db:schema:load Patch mit:

namespace :db do 

    # Helpers 
    def mysql_creation_options(config) 
    @charset = ENV['CHARSET'] || 'utf8' 
    @collation = ENV['COLLATION'] || 'utf8_unicode_ci' 
    {:charset => (config['charset'] || @charset), :collation => (config['collation'] || @collation)} 
    end 

    def load_schema(schema_name) 
    abcs = ActiveRecord::Base.configurations 
    ActiveRecord::Base.connection.recreate_database(abcs[schema_name+'_test']['database'], mysql_creation_options(abcs[schema_name+'_test'])) 
    # like db:test:load_schema 
    ActiveRecord::Base.establish_connection(schema_name+'_test') 
    ActiveRecord::Schema.verbose = false 
    load("#{Rails.root}/db/#{schema_name}_schema.rb") 
    end 

    namespace :schema do 
    # desc 'Dump additional database schema' 
    task :dump => [:environment, :load_config] do 
     dump_schema = -> (schema_name) { 
     filename = "#{Rails.root}/db/#{schema_name}_schema.rb" 
     File.open(filename, 'w:utf-8') do |file| 
      ActiveRecord::Base.establish_connection("#{schema_name}_#{Rails.env}") 
      ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, file) 
     end 
     } 

     dump_schema.call('kiddom') 
     dump_schema.call('kiddom_warehouse') 
    end 

    # When loading from schema, load these files, too 
    task :load => [:environment, :load_config] do 
     load_schema('kiddom') 
     load_schema('kiddom_warehouse') 
    end 
    end 

    namespace :test do 
    # desc 'Purge and load foo_test schema' 
    task :load_schema do 
     load_schema('kiddom') 
     load_schema('kiddom_warehouse') 
    end 
    end 
end 

Aber das gibt mir den Fehler NoMethodError: undefined method 'recreate_database' for #<ActiveRecord::ConnectionAdapters::SQLite3Adapter:0x007feb6bb43558>. Scheinbar funktioniert das nur auf Oracle-Typ-Datenbanken?

Was sind die Rails-Befehle für die zugrunde liegenden DROP und CREATE DATABASE sql Ich versuche, für die zusätzlichen schema.rb s auswirken?

+0

ich mit einem Motor einmal enthalten Modellen gearbeitet. Wir haben nur die Modelle und die Migrationen geteilt und das hat gut funktioniert. Das Schema.rb' haben wir individuell für jede App gehalten; der Motor lieferte keine. Dies macht Sinn, da die Datenbank zu einer App gehört und nicht zu einer Engine. HTH – Raffael

+0

Thx Raffael! In den meisten Fällen stimmen Sie genau: Die Engine fügt neuen Modellcode hinzu oder erweitert bestehende Modelle, und es ist sinnvoll, das Schema.rb in der App zu belassen. In unserem Fall stellt die Engine jedoch Modelle dar, die in einer völlig anderen Datenbank leben. Daher müssen wir für diese Modelle eine andere Schemadatei haben (richtig?) –

+0

Ich sehe. Ich habe nie mit mehreren Datenbanken gearbeitet, obwohl ich immer neugierig war, wie das geht. Anscheinend können Sie verschiedene Datenbanken auf einer Modellklassenbasis verwenden. Es wird ein bisschen knifflig, wenn Sie auch Migrationen auf den zusätzlichen Datenbanken durchführen müssen; siehe http://excid3.com/blog/rails-activerecord-multiple-databases-and-migrations/ – Raffael

Antwort

0

Sie verwenden SQLite als Datenbankmodul. Hoffe, dass du das willst.

Da Sie SQLite-Datenbank erstellen, unterscheiden sich die Dinge ein wenig von anderen Datenbankadaptern wie MySQLAdpter oder Postgress.

Im Fall von MySQL muss die Datenbank erstellt werden, bevor eine Verbindung hergestellt wird, indem "CREATE DATABASE ..." SQL-Befehle ausgegeben werden. Daher müssen Sie die Datenbank vor dem Verbindungsaufbau erstellen.

Aber im Falle von SQLite, da die Datenbank sich in einer Datei befindet und eine Datei nur eine Datenbank enthalten kann, gibt es keinen separaten Schritt zum Erstellen der Datenbank. Wenn Sie versuchen, eine Verbindung zur Datenbank herzustellen, wird die Datenbankdatei erstellt.

Daher create_database Methode funktioniert nicht bei Verwendung von SQLiteAdapter. Sie können diese Zeile einfach aus Ihrem Code entfernen. der Quellcode für 'create' Methode in SQLiteDatabaseTasks erstellen

https://github.com/rails/rails/blob/f47b4236e089b07cb683ee9b7ff8b06111a0ec10/activerecord/lib/active_record/railties/databases.rake

Auch:

Sie können für die Rake Aufgabe db einen Blick auf den Quellcode haben. Wie Sie sehen können, ruft er einfach die establish_connection Methode

https://github.com/rails/rails/blob/f47b4236e089b07cb683ee9b7ff8b06111a0ec10/activerecord/lib/active_record/railties/databases.rake