2015-12-22 50 views
9

Staram się przenieść wszystkie moje udostępnione modele do silnika, który może być zawarty w każdej z moich mikro aplikacji.Jak załadować wiele schematów do silnika lub aplikacji Rails?

Silnik ten powinien stanowić warstwę modelu do wszystkich naszych dotychczasowych danych, w tym:

Pliki modeli są instalowane automatycznie, to dobrze.

plików schematu są małpy załatana w użyciu 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 

Musimy rake db:create i rake db:schema:load do pracy,

The db.rake łat tylko wpływa db:schema:dump i db:test:load_schema (część tests_prepare, zakładam) . Mam próbował załatać je db:schema:load używając:

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 

Ale to daje mi błąd NoMethodError: undefined method 'recreate_database' for #<ActiveRecord::ConnectionAdapters::SQLite3Adapter:0x007feb6bb43558>. Wydaje się, że działa to tylko w bazach danych typu Oracle?

Co to są polecenia Rails dla podstawowych DROP i CREATE DATABASE sql Próbuję wpłynąć na dodatkowe schema.rb s?

+0

Pracowałem z silnikiem zawierającej modele raz. Udostępniliśmy tylko modele i migracje, które działały bez zarzutu. "Schemat.rb "trzymaliśmy indywidualnie dla każdej aplikacji; silnik nie dostarczył żadnego. Ma to sens, ponieważ baza danych należy do aplikacji, a nie do silnika. HTH – Raffael

+0

Thx Raffael! W większości przypadków masz dokładnie rację: silnik dodaje nowy kod modelu lub rozszerza istniejące modele i ma sens, aby pozwolić schema.rb na żywo w aplikacji. W naszym przypadku jednak silnik reprezentuje modele, które żyją w zupełnie innej bazie danych - musimy więc mieć inny plik schematu dla tych modeli (prawda?). –

+0

Rozumiem. Nigdy nie pracowałem z wieloma bazami danych, chociaż zawsze byłem ciekawy jak to zrobić. Wygląda na to, że możesz korzystać z różnych baz danych w zależności od klasy modelu. Robi się trochę trudniej, jeśli musisz uruchomić także migracje w dodatkowych bazach danych; zobacz http://excid3.com/blog/rails-activerecord-multiple-databases-and-migrations/ – Raffael

Odpowiedz

0

Używasz SQLite jako silnika bazy danych. Mam nadzieję, że właśnie to chcesz zrobić.

Ponieważ tworzysz bazę danych SQLite, rzeczy różnią się nieco od innych kart baz danych, takich jak MySQLAdpter lub Postgress.

W przypadku MySQL, baza danych musi zostać utworzona przed ustanowieniem połączenia przez wydawanie komend SQL "CREATE DATABASE ...". Dlatego musisz utworzyć bazę danych przed nawiązaniem połączenia.

Ale w przypadku SQLite, ponieważ baza danych znajduje się w pliku, a jeden plik może zawierać tylko jedną bazę danych, nie ma oddzielnego kroku do utworzenia bazy danych. Próba ustanowienia połączenia z samą bazą danych spowoduje utworzenie pliku bazy danych.

Z tego powodu metoda create_database nie będzie działać podczas korzystania z SQLiteAdapter. Możesz po prostu usunąć tę linię ze swojego kodu.

Możesz rzucić okiem na kod źródłowy dla zadania Rake db: create

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

również kod źródłowy „tworzyć” metody w SQLiteDatabaseTasks. Jak widać, to po prostu wywołuje metodę establish_connection

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