12 Ноя

Подключение к БД MSSQL через ActiveRecord

В общем, понадобилось мне в одном проектике подключаться к двум базам данных одновременно. Причём одна из них должна быть локальная MySQL, а вторая удалённая MSSQL. Информации по этой теме нетак уж и много, особенно на русском языке, поэтому я запишу сюда себе всё ж.

В общем, сначала я столкнулся с проблемой несостыковки кодировок в MySQL. Если заношу данные в базу (и считываю их потом оттуда) на английском языке — то всё нормич, а вот как только дело доходит до русского — приложение Sinatra сразу вылетает с ошибкой. Текст ошибки я сейчас уже не помню, но гугление помогло мне и в итоге я нашел инфу, что для подключения к MySQL необходим адаптер не mysql, как могло сначала показаться, а mysql2. Да не просто mysql2, а ещё и определенной версии. В общем, в моём приложении Gemfile стал выглядеть вот так:

 gem "sinatra"
 gem 'mysql2', '~> 0.3.18'
 gem "activerecord"
 gem "sinatra-activerecord"
 gem "sinatra-contrib"

Далее передо мной возникла проблема подключения к базе MSSQL, в общем, с горем пополам тоже нашел инфу, что для подключения к MSSQL нужны ещё два гема. В итоге Gemfile пополнился ещё двумя строчками:

gem 'tiny_tds'
gem 'activerecord-sqlserver-adapter', '~> 4.2.0'


Ну и, наконец, момент нстал, я запускаю приложение, и на той странице, где я выполняю обращение к MSSQL, получаю такую ошибку:

Incomplete response received from application

При этом код запроса был простейшим:
@request = Request.where("state = 2").count
а в tux’е этот же самый запрос выполнялся абсолютно нормально.
В логах passenger’а было вот такие сообщения:
NoMethodError - undefined method `head?' for 69:Fixnum:
и
Exception NoMethodError in Rack application object (undefined method `path_info' for 69:Fixnum)

Примерно полдня убил я на поиск решения и уже собирался было на кривом английском спрашивать совета на stackoverflow, как наткнулся на такое решение:

Don’t use @request instance variable. Rack stack uses it to store HTTP request there.

То есть эта скотина Rack зарезервировала за собой переменную @request для своих нужд. После переименования переменной в @get_request всё заработало просто идеально.
В общем, как обычно, решение проблемы было достаточно тривиальным.
Такие дела.