little ruby blog

небольшой блог о ruby, rails и разной фигне

Неловкая ситуация

| Comments

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

А теперь, собственно, к сути. Пост-ванлайнер, фактически. Я почему-то был убежден, что yaml-файлы не препроцессятся ERB для ActiveRecord и Mongoid. А сейчас посмотрел в сырцы и убедился, что был неправ.

Afterword: долго не писал, потому что был весьма занят, и к тому же, сменил проект. За это время я успел немного поработать с Phusion Passenger, пощупать за всякое CouchDB, понаблюдать за Riak в качестве файлового хранилища. Ну и, конечно же, немного по(ш)кодить.

Теперь снова буду писать.

Удобная организация маршрутов в Rails-приложении

| Comments

Какая проблема?

В нашем проекте на данный момент файл маршрутов routes.rb занимает уже 180 LOC. И это совсем не предел - к концу проекта он увеличится вдвое, если не втрое. При этом, конечно, использованы все доступные на данный момент в нашей версии Rails(3.2.6) возможности организации маршрутов. В файле маршрутов я начинаю попросту путаться - довольно трудно становится найти необходимое в каше из неймспейсов, вложенных в неймспейсы. К тому же, в экране кода маршрутизации не проще разобраться, чем в любом другом экране кода.

Настало время для реорганизации и уборки!

Мини-виджеты при помощи CoffeeScript. Немного магии

| Comments

Preamble: по примеру предыдущего поста теперь, показывая какие-либо решения, я буду стараться оформлять их как в предыдущем посте - то есть, формулировать проблему, описывать решение, описывать использование решения и, если есть необходимость, показывать подводные камни решения. Мне кажется, такая форма вполне понятна и имеет право на успех. Читатели, отзовитесь, пожалуйста, в комментариях.

Preamble #2: этот пост посвящается неоднократно упомянутому мной и хорошо известному Богдану Гусеву. Богдан, с днём рождения! Я немного улучшил твое решение :)

Какая проблема?

На своем текущем проекте довелось заметить, что часто требуется менее богатая функциональность, чем та, которую предлагают javascript UI библиотеки, но более динамическая, нежели простое отображение результата на отдельной странице.

Классически принято решать подобные вещи достаточно низкоуровневым путем: создается javascript-обработчик, навешивается на определенный селектор, в нужную область выводятся данные. Но что делать, если однотипных решений несколько? Не очень хочется поддерживать несколько почти одинаковых скриптов, да еще и следить за актуальностью селекторов, потому что на проекте с богатой функциональностью большая часть классов CSS на самом деле используется для скриптов.

Такое решение приводит к низкой сопровождаемости верстки, перенасыщению HTML-кода классами. И как итог - становится очень легко всё поломать.

Rails-маршруты в Javascript

| Comments

Какая проблема?

Каждому фронтэнд-девелоперу наверняка знакома проблема поддержки актуальными маршрутов в java- или coffeescript. Поменялась схема маршрутов - и вот, снова нужно переписывать тонны скриптов, меняя в них всех URL.

Как решить?

Решение, как и в предыдущем посте, предложили Railsware, а вернее - по большей части Богдан Гусев.

Гем называется js-routes, в его задачу входит генерировать объект Routes (он может называться иначе), который содержит в себе маршруты в виде функций - то есть, вы можете вместо набивших оскомину ручных заполнений маршрутов использовать код вида:

1
  console.log(Routes.action_controller_path(id))

Закон Деметры или как избежать спагетти-ассоциаций

| Comments

Что такое закон Деметры?

Читая Rails antipatterns, я натолкнулся на упоминание одного принципа, о котором раньше не слышал (стыд мне!). Звучало его название как “Закон Деметры”.

Что же такое закон Деметры? Вкратце, это такое правило дизайна для ПО, в частности - для объектно-ориентированного. Был сформулирован в конце 1987 года в Бостоне и в наиболее краткой формулировке звучит так:

Не разговаривай с незнакомцами!

Если развернуть это определение, то объект A не должен иметь возможность получить непосредственный доступ к объекту C, если у объекта A есть доступ к объекту B и у объекта B есть доступ к объекту C.

Немного о совместных шаблонах

| Comments

Почти каждый из нас когда-либо пробовал писать или писал приложения с динамически обновляемым контентом. Пока схема контента несложная - все достаточно просто и неизбыточно. Но как только оформление и количество контента достигает определенной сложности - начинаются проблемы.

Основная проблема - это поддержка одновременно двух шаблонов отображения (для клиента и для сервера). Чтобы этого избежать, обычно прикручивают шаблонизатор того же рода и на стороне сервера.

Алексей Васильев из RailsWare помог избежать и этой проблемы, причем при помощи сразу двух гемов.

Первый из них называется smt_rails и используется, если вы предпочитаете Mustache в качестве шаблонизатора.

Второй - sht_rails и используется для Handlebars.

Установка

Установку я рассмотрю на примере Handlebars, но вообще она фактически совпадает и для Mustache.

Первым делом в Gemfile мы добавляем следующий код: <div class=’bogus-wrapper’>

<div class=”highlight”><table><tr><td class=”gutter”><pre class=”line-numbers”>1 </pre></td><td class=’code’><pre>gem 'sht_rails', github: "rails/sht_rails"</pre></td></tr></table></div>
</div> Потом запускаем генератор: <div class=’bogus-wrapper’>
<div class=”highlight”><table><tr><td class=”gutter”><pre class=”line-numbers”>1 </pre></td><td class=’code’><pre>rails g sht_rails:install</pre></td></tr></table></div>
</div>

Использование

В директории app/templates создаем наш partial с расширением .template.

Для его рендера из рельсов выполняем следующий код: <div class=’bogus-wrapper’>

<div class=”highlight”><table><tr><td class=”gutter”><pre class=”line-numbers”>1 </pre></td><td class=’code’><pre><%= render 'partial', handlebars: content.as_json %></pre></td></tr></table></div>
</div>

А в JavaScript поступаем следующим образом: <div class=’bogus-wrapper’>

<div class=”highlight”><table><tr><td class=”gutter”><pre class=”line-numbers”>1 2 </pre></td><td class=’code’><pre>var content = ... ; ajax call with json result var rendered = SHT['partial'](content)</pre></td></tr></table></div>
</div>

Пример использования

На пример использования можно посмотреть здесь, а исходники глянуть здесь.

Удачного использования!

История дурацкой ошибки или читайте документацию

| Comments

Умудрился полдня потратить на непонятную ошибку. Всё было как обычно - создал проект, накатил туда RSpec, Capybara и Poltergeist, насочинял фабрик для FactoryGirl - и тут внезапно обнаружил, что тесты, которые завязаны на фабриках - не проходят.

Причем поведение тестов очень странное. Данные в контексте теста - создаются, pry мне это абсолютно чётко доказал. А вот в контроллере, где идет работа с этими данными - пусто.

Спасибо Богдану Гусеву, отпустил замечание, что из такого странного поведения следует, что данные в контексте теста и в контексте контроллера - разные транзакции.

И после этого в spec_helper.rb обнаружилась одна строчка, которая туда пришла из генератора RSpec. Собственно, после установки параметра use_transactional_fixtures в false и пропало необычное поведение, тесты начали работать.

Сейчас изучаю, почему же всё вело себя именно так.

P.S. Одно запомнил надолго - spec_helper.rb по умолчанию для FactoryGirl не подходит. Кстати, мне кажется, или фикстуры уже немного менее популярны, чем FactoryGirl?

Создание собственного блога на базе Github и Octopress

| Comments

Disclaimer: Всю информацию, которую можно извлечь из этого поста, также можно извлечь и из официальной документации по Octopress. #### Предварительная подготовка и получение исходников Первым делом нам необходимо завести репозиторий на Github, в котором будут находиться исходники нашего блога. Если верить документации Github, то для создания блога пользователя или организации нам сначала необходимо создать репозиторий с именем вида username.github.com.

Внимание! Не стоит создавать репозиторий без “.github.com”, так как в этом случае Octopress распознает репозиторий как репозиторий для github project pages. А это совсем не то, чего мы хотим.

Initial Post

| Comments

Обо мне

#### Приветствие Привет. Меня зовут Михаил Бортник, я Ruby-программист. Поскольку мой основной блог на juick стал содержать в себе слишком много ruby-кода и слишком мало личной информации, то всё, что касается программирования, переедет сюда. Поскольку опыт в программировании на Ruby у меня не очень большой - иногда здесь я буду играть в капитана Очевидность или проявлять некоторую поспешность суждений. Пожалуйста, относитесь к этому со снисхождением и пониманием.