Ответы пользователя по тегу Ruby on Rails
  • Использование нескольких баз данных в Rails 3: как?

    @MOZGIII Автор вопроса
    Я нашёл решение! Ура!

    Главный сахар
    app/models/wow/base.rb
    class Wow::Base < ActiveRecord::Base
      self.abstract_class = true
      
      class << self
      
        def [](database_id)
          raise "DB name was not set! Use set_db_name to set it in yor model!" unless db_name
          self.abstract_class = true
          class_name = "#{database_id.to_s.classify}_#{self.name}"
          
          return Object.const_get(class_name) if Object.const_defined?(class_name)
          
          db_info = connection_info(database_id)
          raise ArgumentError, "There is no database with such ID!" unless db_info
          
          klass = Object.const_set class_name, Class.new(self)
          klass.establish_connection(db_info)
          klass
        end
        
        def set_db_name name; @@db_name = name; end
        def db_name; @@db_name; end
        
        private
        
        def connection_info database_id
          # эту не поясняю т.к. длинно, должна возвращать то, что принимает establish_connection
          WOW_CONFIG[database_id][:databases][db_name] 
        end
        
      end
    end


    Потом для всех баз создаём по файлу, в моём случае:
    app/models/wow/characters_db.rb
    app/models/wow/mangos_db.rb
    app/models/wow/realmd_db.rb
    app/models/wow/scriptdev2_db.rb

    С примерно таким содержимым (пример для characters_db.rb, заменять подчёркнутое):

    app/models/wow/characters_db.rb
    class Wow::CharactersDb < Wow::Base
    self.abstract_class = true
    set_db_name :characters
    end


    Вот и всё!!! Ну, почти… :) Теперь немного изменим все файлы моделей, наследуем их все от нужных нам таблиц:

    app/models/characters.rb
    class Character < Wow::CharactersDb
    set_primary_key :guid
    belongs_to :account, :foreign_key => :account

    scope :online, where(:online => 1)
    scope :offline, where(:online => 0)

    scope :alliance, where(:race => [1,3,4,7,11])
    scope :horde, where(:race => [2,5,6,8,10])
    end


    И для отсальных моделей производим аналогичные замены.
    Использовать после всего этого так:
    Character[:main].count
    Account[:legacy].all
    … и т.п.
    Это толком не протестировано на работу миграций, ассоциаций и прочего, но уже ночь, поду вообщем спать… :) Всем кто задумался над проблемой спасибо.
    PS: что-то мне думается что с ассоциациями будет всё в порядке… Хотя может в одном месте поменять кое-что надо (там где "...}_#{...")…
    Ответ написан
    3 комментария