2015-12-22 19 views
9

Tüm paylaşılan modellerimi, mikro uygulamalarımın her birine dahil edilebilecek bir motora taşımak istiyor.Rails motoruna veya uygulamasına birden çok şema nasıl yüklenir?

Bu motor da dahil olmak üzere tüm eski verilerine bir modeli katmanı sağlamak olmalıdır:

  • Modeli dosyalarının
  • Şema dosyaları
  • Göçler (biz Pivotal Labs' pattern takip ediyoruz, bu sorun değildir)

Model dosyaları otomatik olarak yamanıyor, bu iyi.

şema dosyaları Nikolay Strum's db.rake kullanarak maymun yamalı ediliyor:

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 

Biz işe rake db:create ve rake db:schema:load ihtiyaç

db.rake yamalar

sadece db:schema:dump ve db:test:load_schema etkiler (tests_prepare kısmını sanırım) . Kullandığım db:schema:load bunları yama teşebbüs ettik:

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 

Ama bu bana hata NoMethodError: undefined method 'recreate_database' for #<ActiveRecord::ConnectionAdapters::SQLite3Adapter:0x007feb6bb43558> veriyor. Anlaşılan, bu sadece Oracle tipi veritabanlarında çalışıyor mu?

Alttaki DROP ve CREATE DATABASE sql için Rails komutları nelerdir Ekstra schema.rb için etkilemeye çalışıyorum 's?

+0

establish_connection yöntemini çağırır. Sadece modelleri ve göçleri paylaştık ve işe yaradı. Şema.her uygulama için ayrı ayrı tutulduk; motor sağlanmadı. Veri tabanı, bir motora değil, bir uygulamaya ait olduğu için bu mantıklıdır. HTH – Raffael

+0

Thx Raffael! Çoğu durumda, tam olarak haklısınız: Motor yeni model kodu ekler veya mevcut modelleri genişletir ve schema.rb'nin uygulamada canlı kalmasına izin vermeniz mantıklıdır. Ancak bizim durumumuzda, motor tamamen farklı bir veritabanında yaşayan modelleri temsil ediyor - bu yüzden bu modeller için farklı bir şema dosyasına sahip olmamız gerekiyor (sağda?) –

+0

Anladım. Bunu nasıl yapacağımı merak etsem de, birden fazla veritabanında hiç çalışmamıştım. Görünüşe göre, model başına bir temelde farklı veritabanları kullanabilirsiniz. Ek veritabanlarında da geçişleri çalıştırmanız gerekirse biraz daha zorlaşır. bkz. http://excid3.com/blog/rails-activerecord-multiple-databases-and-migrations/ – Raffael

cevap

0

SQLite, veritabanı motorunuz olarak kullanıyorsunuz. Umarım yapmak istediğin budur.

SQLite Veritabanı oluşturduğunuz için, işler MySQLAdpter veya Postgress gibi diğer veritabanı bağdaştırıcılarından biraz farklıdır.

MySQL durumunda, veritabanı "CREAT DATABASE ..." SQL komutları kullanarak bir bağlantı kurmadan önce oluşturulmalıdır. Yani bağlantı kurmadan önce veritabanını oluşturmanız gerekir.

Ancak SQLite söz konusu olduğunda, veritabanı bir dosyada bulunduğundan ve bir dosya yalnızca bir veritabanı içerebildiğinden, veritabanı oluşturmak için ayrı bir adım yoktur. Veritabanına kendisi için bir bağlantı kurma girişimi, veritabanı dosyasının oluşturulmasına neden olur. SQLiteAdapter kullanıldığında create_database yöntemi çalışmaz. Bu nedenle, create_database yöntemi çalışmayacaktır. Bu satırı sadece kodunuzdan kaldırabilirsiniz.

Sen Rake görev db için kaynak koduna bir göz olabilir: Ayrıca

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

oluşturmak, SQLiteDatabaseTasks içinde 'create' yöntemi için kaynak kodu. Gördüğünüz gibi, sadece bir kez modelleri içeren bir motor ile çalışan

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

İlgili konular