О редакторе Vim, рассказ ссылками
Vim — прекрасный редактор, который я использую для разработки на Ruby и Rails. Его можно использовать в чистом виде, но если добавить немного плагинов, то удобство работы значительно возрастает. Об этом я и хочу рассказать, правда рассказ получится длинным.
Я выступал на последнем RailsClub’е с докладом Vim Or Die (посмотреть его можно на univertv.ru), в котором неплохо раскрыл тему Vim и полезных плагинов. Cами слайды, которые малополезны без видео, можно найти на slideshare.net.
Англоязычные подкасты про ruby и rails
Так сложилось, что я управляю транспортным средством больше, чем час в день (на работу, на тренировку, домой). И я давно уже хотел слушать английские тексты в это время, потому что музыка часто надоедает.
Я пробовал слушать «обычные» тексты, но потом подумал, что гораздо интереснее слушать то, что тебя волнует. Поэтому я порылся в дебрях интернета и нашел следующие подкасты, которые я регулярно слушаю.
The Ruby Show — выходит по вторникам, длится минут 15-20. Две веселых чувака рассказывают про новости в мире ruby и rails, при этом периодически достаточно весело шутят.
Переопределение Rails.logger и проблемы с ним
Часто один и тот же rails-проект используется и для web-части, и для каких-то других задач, выполняемых по расписанию или для создания демонов. В таких случаях иногда хочется, чтобы логи разных частей писались в разные файлы.
Готового способа для этого я не нашел. Например, посмотрим на такой пример:
$ ./script/console
Loading development environment (Rails 2.3.5)
>> ActiveRecord::Base.logger = Logger.new(STDOUT)
=> #<Logger:0xb192594 @progname=nil, @level=0, @default_formatter=#<Logger::Formatter:0xb19255c @datetime_format=nil>, formatternil, logdev#<Logger::LogDevice:0xb19247c @shift_size=nil, @shift_age=nil, @filename=nil, @dev=#<IO:<STDOUT>, mutex#<Logger::LogDevice::LogDeviceMutex:0xb192444 @mon_owner=nil, @mon_count=0, @mon_mutex=#<Mutex:0xb19240c>
>> User.first
=> #<User id: 1, email: "seeduser@scalaxy.ru" ...>
>>
И где же логи, спросите вы?
Автоматизация vim с помощью pathogen
Извечная проблема о том, как добавлять и обновлять плагины в vim решилась благодаря легендарному Tim Pope.
Сегодня утром узнал от Ярослава Маркина о существовании pathogen.
Статья на английском о том, как им пользоваться, лежит здесь. Правда, я потратил полчаса, чтобы
догадаться, что надо добавить call pathogen#runtime_append_all_bundles()
в файл ~/.vimrc
.
После установки pathogen.vim в
можно хранить все плагины в папке /.vim/autoload/.vim/bundle
, причем каждый в своей папке.
А еще огромный плюс - в конце этой статьи код, который позволяет обновлять все плагины одной командой.
Использование ruby-debug
Использование дебаггера при разработке — это плохой тон. Это значит, что вы не понимаете, как работает ваша программа. Но иногда жизнь без дебаггера становится невыносимой.
Есть отличный плагин vim-ruby-debugger для редактора vim. Но он пока сыроват и не все возможности в нем есть. По крайней мере в моем случае, чтобы понять, что происходить внутри спека, он не помог.
Тогда я воспользовался старым дедовским способом:
require 'ruby-debug'
Debugger.start
И вставил вызов debugger в том месте, где мне это необходимо.
PgQ и Londiste
Хотя я так и не написал толком, как пользоваться PgQ и Londiste, но уже написал плагин, который облегчает его использование вместе с рельсами.
http://github.com/evtuhovich/pgq/tree/master
В README всё написано на плохом английском (с хорошим английским у меня плохо).
Совсем скоро я добавлю туда возможность прогонять миграции на master и slave базах данных одновременно. Тогда при очередной выкатке необходимо будет сделать только rake londiste:update в самом конце, после того, как все миграции прогонятся.
Проблема с проверкой уникальности какого-то поля в rails
Пусть в модели User у нас описана валидация для поля email
validates_uniqueness_of :email, :case_sensitive => false,
:message => i18n_proxy(:email_already_registered)
Следующий код генерирует вот такой запрос к базе данных:
SELECT * FROM users WHERE lower(email) = 'thmth' LIMIT 1
А на таблице users у нас индекс по полю email. В postgresql запрос, что вверху, не будет использовать индекс. Представьте, что будет, когда в таблице users десятки тысяч записей, а на каждое изменение любого поля в users вызывается такой запрос.
Именно это я наблюдал совсем недавно на нашей живой базе. Проблема решается
просто, например, убрать :case_sensetive
, а email всегда
предварительно переводить в нижние буквы.
Перенос таблицы в другую базу данных postgres без простоя приложения
В продолжении темы о нескольких базах данных в одном rails-приложении расскажу о том, как изящно перенести одну большую таблицу в другую БД postgresql.
Пусть у нас есть таблица messages с большим количеством данных (10 миллионов записей), которые мы решили перенести на другой сервер. Мы сделали, как написано в статье, указанной выше, а также создали в новой БД таблицу messages с такой же структурой.
Теперь с помощью londiste настраиваем репликацию из первой БД во вторую для таблицы messages (об этом я напишу подробнее попозже, пока же можно прочитать об этом у Андрея Стихеева в рассылке ror2ru).
Несколько баз данных
В некоторых ситуациях необходимо использовать более чем одну базу данных в проекте. Например, статистику и большие таблицы хранить на другом сервере, у которого большой и медленный диск, а данные, которые нужны постоянно, хранить на основном сервере с маленьким и быстрым диском.
В нашем случае хотелось унести большие таблицы на другой сервер, чтобы в дисковом кэше (а у главного сервера БД 32 Гб оперативной памяти) хранились все рабочие таблицы и никогда оттуда не убегали.
Рекурсивные особенности to_yaml
Если необходимо сериализовать/десериализовать какой-то объект, то yaml формат хорошо для этого подходит.
В моем проекте мы записывали объекты в очередь, использую yaml-сериализацию. На тестах все было хорошо. Но на живом эта самая сериализация стала выполняться очень долго.
Оказалось, что если у объекта есть связные объекты, то он их тоже засовывает в yaml, а если таких объектов очень много, то это будет сложная операция. Понятно, что в примитивных тестах этого было не видно, а подумать хорошо головой в тот раз не получилось.