Ruby: Rails: MRI и JRuby

#mysql #ruby-on-rails #ruby #jruby

#mysql #ruby-on-rails #ruby #jruby

Вопрос:

Я перенес свое приложение Rails 3.0.10 / MRI на Ubuntu 11.04 на JRuby 1.6.4 на Ubuntu 11.04. Моя цель — добраться до места, где мне просто нужно сделать следующее, чтобы запустить приложение под JRuby.

 railsapp1> rbenv local jruby-1.6.4
railsapp1> rails server
  

И чтобы приложение работало под MRI,

 railsapp1> rbenv local 1.9.2-p290
railsapp1> rails server
  

Первая часть этой проблемы заключалась в разрешении драгоценных камней. Чтобы заставить этот процесс работать без изменений кода, я сделал следующее в файле Rails Gemfile

 platforms :mri do
    gem 'mysql2', '~>0.2.11'
end
platforms :jruby do
    gem 'jruby-openssl'
    gem 'activerecord-jdbcmysql-adapter'
end
  

Эти инструкции gem были получены с использованием метода грубой силы путем создания фиктивных приложений rails с различными комбинациями MRI / JRuby и SQLite / MySQL, а затем получения инструкций gem из сгенерированных файлов Gemfile для каждой комбинации.

Однако это не совсем так. Мой файл config / database.yml выглядит следующим образом:

 development:
    adapter: mysql2
    database: doodad
    username: doodad
    password: doodad
    host: localhost
  

Этот файл config / database.yml работает только для версии MRI. Для версии JRuby файл config/database.yml выглядит следующим образом:

 development:
    adapter: mysql
    database: doodad
    username: doodad
    password: doodad
    host: localhost
  

т. е. Единственное различие между файлами — это имя адаптера базы данных (mysql vs mysql2). Есть ли способ указать файлу database.yml или системному инициализатору выбрать адаптер в зависимости от того, является ли среда Ruby MRI или JRuby?

Ответ №1:

Вы можете использовать ERB в вашем файле database.yml:

 development:
  adapter: <%= defined?(JRUBY_VERSION) ? "mysql" : "mysql2" %>
  ...
  

Комментарии:

1. Спасибо! В конце концов я пошел с адаптером: <%= RUBY_ENGINE==»jruby» ? «mysql»: «mysql2» %>

Ответ №2:

Если все, что вам нужно сделать, это перевернуть ваш database.yml файл, у вас это довольно хорошо. Я обычно избегаю проверять это в репозитории, поскольку разные разработчики имеют разные конфигурации, вместо этого предоставляя только файл примера.

Аналогично, когда дело доходит до развертывания, сервер имеет постоянный файл конфигурации, который используется совместно между развертываниями. Это позволяет вам точно настроить настройки без необходимости вносить изменения в свой репозиторий только для размещения нечетного пограничного случая на одном сервере.

Если вас это все еще беспокоит, вы могли бы создать оболочку вокруг mysql драгоценного камня JRuby, которая регистрирует его как mysql2 для целей конфигурации, но это, вероятно, опасная игра, поскольку вы в основном лжете в своей конфигурации, вводя в заблуждение людей, которые могут захотеть диагностировать проблему, с которой они столкнулись. Люди в этом смысле включают в себя «будущих вас», которые забыли об этом взломе.

Более безопасная альтернатива — иметь две разные, но похожие среды для разработки. Вы можете называть их как хотите:

 development_common: amp;development_common
  database: doodad
  username: doodad
  password: doodad
  host: localhost

development_jruby:
  <<: *development_common
  adapter: mysql

development_ruby:
  <<: *development_common
  adapter: mysql2
  

Не так сложно настроить вашу локальную среду так, чтобы она была той или иной по мере необходимости, или переключаться между ними, устанавливая RAILS_ENV по мере необходимости, если вы выполняете интеграционные тесты в обоих мирах.

Комментарии:

1. Буду ли я тогда запускать свой сервер как «rails server -e development_jruby» или «rails server -e development_ruby»?

2. Это один из способов сделать это. Существует также возможность сделать RAILS_ENV=development_jruby rails server так, чтобы большинство оболочек временно устанавливали переменные среды.