2015-12-22 38 views
9

Cerco di spostare tutti i miei modelli condivisi su un motore che può essere incluso in ciascuna delle mie micro app.Come caricare più schemi in un motore o in un'app Rails?

Questo motore dovrebbe fornire un livello di modello a tutti i nostri dati legacy, tra cui:

I file di modello vengono corretti automaticamente, va bene.

file di schema vengono scimmia-patch utilizzando Nikolay Strum's db.rake:

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 

Abbiamo bisogno rake db:create e rake db:schema:load a lavorare,

I db.rake patch effetto solo db:schema:dump e db:test:load_schema (parte di tests_prepare, presumo) . Ho cercato di rattoppare loro in db:schema:load utilizzando:

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 

Ma questo mi dà l'errore NoMethodError: undefined method 'recreate_database' for #<ActiveRecord::ConnectionAdapters::SQLite3Adapter:0x007feb6bb43558>. Apparentemente, questo funziona solo su database di tipo Oracle?

Quali sono i comandi Rails per il sottostante DROP e CREATE DATABASE sql che sto tentando di modificare per gli extra schema.rb?

+0

ho lavorato con un motore che contiene modelli una volta. Abbiamo condiviso solo i modelli e le migrazioni e questo ha funzionato correttamente. Lo schema.rb' abbiamo tenuto individualmente per ogni app; il motore non ne ha fornito. Questo ha senso perché il database appartiene a un'app, non a un motore. HTH – Raffael

+0

Thx Raffael! Nella maggior parte dei casi, hai esattamente ragione: il motore aggiunge un nuovo codice modello o estende i modelli esistenti e ha senso lasciare che lo schema.rb risieda nell'app. Nel nostro caso, tuttavia, il motore rappresenta i modelli che vivono in un database completamente diverso, quindi è necessario disporre di un file di schema diverso per questi modelli (vero?) –

+0

, vedo. Non ho mai lavorato con più database, anche se ero sempre curioso di sapere come farlo. Apparentemente è possibile utilizzare diversi database su base di classe per modello. Diventa un po 'ingannevole se è necessario eseguire le migrazioni anche sui database aggiuntivi; vedi http://excid3.com/blog/rails-activerecord-multiple-databases-and-migrations/ – Raffael

risposta

0

Si sta utilizzando SQLite come motore del database. Spero che sia quello che vuoi fare.

Poiché si sta creando un database SQLite, le cose differiscono un po 'da altre schede di database come MySQLAdpter o Postgress.

Nel caso di MySQL, il database deve essere creato prima di stabilire una connessione spendendo comandi SQL "CREATE DATABASE ...". Quindi è necessario creare il database prima di stabilire una connessione.

Ma nel caso di SQLite, poiché il database risiede in un file e un file può contenere solo un database, non esiste un passaggio separato per creare il database. Un tentativo di stabilire una connessione al database stesso causerà la creazione del file del database.

Quindi il metodo create_database non funzionerà quando si utilizza SQLiteAdapter. Puoi semplicemente rimuovere quella linea dal tuo codice.

Si può avere uno sguardo al codice sorgente per il compito db Rake: creare

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

Inoltre, il codice sorgente per il metodo di 'creare' in SQLiteDatabaseTasks. Come si può vedere, si chiama semplicemente il metodo establish_connection

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