Пишу сайт, который должен будет работать с со сложной системой, имеющей свою, не рельсовую, структуру БД. Если говорить более конкретно — это сайт для обслуживания инфраструктуры серверов WOW на форке MaNGOS. Сложностей тут прилично: начиная с того, что в таблицах MaNGOS-a не всегда выполняются принятые в Rails и ActiveRecord соглашения, и заканчивая тем, что баз, с которыми нужно работать много: 1 общая realmd база c таблицами account итп, и по 3 (characters_N, mangos_N, scriptdev2_N) для каждого реалма (игрового мира). Сейчас крутится 2 реалма, поэтому всего баз, с которыми нужно работать 1 + 2*3 = 7. Ну ещё для самого сайта заведена отдельная база.
Вот последнюю проблему то (про несколько баз) я и не знаю как решать. Хотелось бы остаться на ActiveRecord, потому что к нему привык уже, поэтому DataMapper и альтернативы рассматриваются в последнюю очередь.
Структуры баз и таблиц в базах characters_N, mangos_N и scriptdev2_N похожи, но в некоторых местах различаются. Например в таблице characters_1.characters 29 столбцов, а в characters_2.characters их 30, добавился один столбец, но все такие изменения несущественны и могут быть опущены в модели.
И вот, вопрос, как удобнее организовать работу с такими базами… Задача, наверное, весьма нетривиальна для Rails программистов.
Кроме того хочется сделать модульную систему, что-бы можно было потом легко расширять количество миров и соответственно добавлять в систему characters_N+1, mangos_N+1 и scriptdev2_N+1 таблицы. Плюс хотелось бы иметь возможность создать модель, может быть без базы, но что-бы она имела все эти базы миров, и можно было бы делать что-то вроде World.each { |w| puts w.characters.online }, где online — это метод модели в таблице characters_N.characters.
Я пока-что мусолю следующую идею: сделать для каждой базы в модели отдельный неймспейс (соответственно отдельную директорию: app\models\wow\server_N\ например), и копировать туда все модели, потом в каждой менять неймспейс и establish_connection к нужной базе делать…
Напрмер так как то:
<pre>
class Wow::Base < ActiveRecord::Base
# ... тут что-то посвященное всем моделям из того
def server_name
# тут по неймспейсу определим номер нужной нам группы серверов
1 # например выдается единица
end
def database_name database, name; "#{database.to_s}_#{id}" end
end
class Wow::Server1::Base < Wow::Base
end
class Wow::Server1::Character < Wow::Server1::Base
# тут соединяемся как-то так
establish_connection database_name(:characters, server_name)
end
</pre><br/>
Тогда в контроллере можно было-бы использовать их так: @chars = Wow::Server1::Character.where(:online => 1).all
Но тогда возникает проблема модульности, да и вообще, плохо это, когда константы (в неймспейсе, а именно Server1) в таком участвуют. Может можно сделать как-нибудь вроде Wow::Server[1]::Character.all или SERVERS[1]::Characters.all или Wow::Characters[1].all или Wow::Characters.set_server(1).all… Кстати последнее я, возможно, даже знаю как реализовать… Только вот не уверен, что ассоциации (has_many, etc) будут работать :) Но всё ровно: что же ещё можно придумать?
Может можно попробовать применять метод расширения модели (гугль по «Rails model extensions (mincemeat models revisited)» ).
Вообщем насколько логично это всё выглядит и у кого какие есть ещё идеи? Помогите, а то уже голова всё не вмещает…