Первое знакомство с Ruby on Rails

    Ruby on Rails (в дальнейшем просто рельсы) это веб фреймворк, написанный на языке Ruby.
    На хабре есть несколько статей о языке, думаю их будет полезно почитать, если возникнут затруднения – читайте википедию, лучшую книгу о языке – Programming Ruby, лучшую книгу о рельсах – Agile Development with Rails, и задавайте вопросы.

    Начнем знакомство с установки Ruby и Rails.



    Пользователям Windows нужно скачать и установить One-click Ruby installer.

    Пользователям Linux (Ubuntu) установить Ruby еще проще:

    <code class='sh' lang='sh'>$>sudo apt-get install ruby rubygems rake</code>


    Убедимся что Ruby работает

    <code class='sh' lang='sh'>$>ruby -v
    ruby 1.8.5 (2006-08-25) [i486-linux]</code>


    и поставим рельсы:

    <code class='sh' lang='sh'>$>gem install rails --include-dependencies
    $>rails -v
    Rails 1.2.3</code>


    Все что вам нужно для начала это текствый редактор с подсветкой синтаксиса Ruby и умение выполнять команды из консоли.
    Для любителей IDE могу посоветовать Aptana, я пишу код в ней (мне просто нравится Eclipse :).
    Все примеры я буду приводить для консоли, что делать в Aptana должно быть понятно, я могу написать об этом отдельно.

    Теперь все готово чтобы начать новый проект.



    Проект на рельсах начинается с создания скелета проекта:

    <code class='sh' lang='sh'>$>rails ~/projects/example</code>


    будет создана папка example и скелет проекта в ней (не забудьте заменить путь на свой). Посмотрим что внутри.

    • app – здесь будет код приложения: модели, вьюшки и контроллеры
    • components – это наследие старых версий, сейчас компоненты не используются
    • config – конфигурация приложения: прежде всего нас будут интересовать
    • параметры соединения с БД и маршрутизация URL на методы контроллеров
    • db – конфигурация создаваемых в БД таблиц будет храниться здесь
    • doc – документация, генерируется из комментариев в коде
    • lib – здесь можно разместить код полезных библиотек
    • log – логи веб сервера
    • public – корневая папка веб сервера, здесь лежит статический контент
    • script – очень полезные для разработки скрипты
    • test — тесты
    • tmp – здесь по умолчанию хранятся сессии пользователей и pid файлы
    • vendor – здесь будут плагины, которые мы будем использовать


    Самое время запустить веб-сервер и убедиться что приложение работает. Идем в папку с приложением и запускаем веб-сервер, поставляемый с рельсами:

    <code class='sh' lang='sh'>$>ruby script/server
    ruby в начале строки нужно писать только в Windows.</code>


    http://localhost:3000/

    Открываем эту линку в своем любимом браузере и наблюдаем страничку «Welcome aboard» – значит все хорошо и пришло время написать простенькое приложение.

    Какое приложение стоит написать?



    Дело в том, что я умею писать текст с человеческой разметкой (Wiki, Markdown, Textile), но хабр поддерживает только html для разметки текста, а мне не удобно писать html когда я хочу просто написать текст.
    Поэтому приложение будет форматировать текст в html!

    Изначально оно будет очень простым, потребуется всего две странички: на первой можно будет ввести текст, а на второй посмотреть его в отформатированном виде и скопировать получившийся html (чтобы запостить на хабр :).

    Начинаем писать код.



    Для ленивых я выложил исходный код приложения, но все же писать код самому интереснее.

    Думаю ни для кого не секрет что паттерн MVC стал де-факто стандартом архитектуры веб приложений. Рельсы не исключение, приложение состоит из моделей, вьюшек и контроллеров.

    Сейчас и в будущем мы будем использовать скрипты которые сделают за нас всю рутинную работу, первый с которым мы познакомимся это generate, он генерирует код.

    <code class='sh' lang='sh'>Создадим контроллер (я назвал его formatting_controller) с двумя методами (вьюшками):
    input – для ввода текста  
    preview – для просмотра форматированного текста
    
    $>ruby script/generate controller formatting input preview</code>


    В результате рельсы сгенерировали несколько файлов из которых сейчас интересны следующие:

    <code class='sh' lang='sh'>app/controllers/formatting_controller.rb
    app/views/formatting/input.rhtml
    app/views/formatting/preview.rhtml</code>


    Как же увидеть сгенерированные страницы в браузере?

    http://localhost:3000/formatting/input

    http://localhost:3000/formatting/preview

    Почему такие урлы?



    За внешний вид урлов в рельсах отвечает модуль Routing, настроить его можно в файле

    <code class='sh' lang='sh'>config/routes.rb</code>


    Сейчас я не буду вдаваться в детали роутинга, об этом можно написать отдельную статью. Сейчас просто добавьте эти две строчки и я обьясню их назначение.

    <code class='ruby' lang='ruby'>map.connect '', :controller => 'formatting', :action => 'input', :conditions => { :method => :get }
    map.preview '', :controller => 'formatting', :action => 'preview', :conditions => { :method => :post }</code>


    connect и preview это вызовы методов. Первый аргумент это путь, в нашем случае путь пустой, тоесть это правила для корня сайта. Второй аргумент это хеш, который содержит какой метод у какого контроллера нужно вызвать и при каких условиях. Тоесть если приходит HTTP GET для корня сайта, то будет вызван метод input, а если HTTP POST, то preview.

    Чем вызов connect отличается от вызова preview?
    Connect это метод, который добавляет правило для роутера, а вот метода preview не существует.
    Это обычное дело для Ruby, в случае когда метода не существует вызывается method_missing в котором можно делать полезные вещи. В нашем случае происходит следующее:

    • В таблицу роутера добавляется правило, какбудто мы вызвали connect
    • Создается метод preview_url, который можно использовать в контроллерах и вьюшках, это называется именованный урл


    Теперь нужно удалить или переименовать public/index.html чтобы вместо этой сранички вызывался метод input и проверить что он действительно вызывается.

    Настала пора вьюшкам показать что-то более полезное.



    Начнем с input.rhtml, заменяем на такой код:

    <code class='ruby' lang='ruby'><% form_tag preview_url do %>
    <%= text_area_tag :text, @source, :size => '120x25' %>
    <%= submit_tag 'Preview' %>
    <% end %></code>


    Получилась страничка с формой, которая будет запощена на preview_url, внутри формы текстовое поле и кнопка для отправки. Теперь возьмемся за форматирование введенного текста.

    Сначала нужно решить как форматировать введенный текст. Эту статью я форматирую как markdown, а для разнообразия решил добавить textile.
    Для поддержки textile и markdown потребуется установить RedCloth и Maruku.

    <code>$>gem install redcloth maruku</code>


    Теперь нужно написать код, который будет форматировать текст. К сожалению я не могу разместить код в статье, потому что хабр его режет, так что лучше открыть formatting_controller.rb в другом окне и переключаться по мере чтения. Что тут к чему.

    • require – подключает нужные гемы (модули, пакеты)
    • before_filter – добавляет метод set_supported_formats в очеред фильтров, которые вызываются перед вызовом экшена
    • params – хеш с параметрами, переданными в запросе


    Для чего потребовался set_supported_formats и что означают все эти @?
    Переменные со знаком @ вначале это переменные обьекта у которого вызывается метод — тоесть контроллера. Дело в том, что вьюшка имеет доступ к переменным контроллера, какбудто это её собственные переменные, поэтому обычно в контроллере выставляются переменные а во вьюшке они используются для рендеринга. В preview.rhtml мы будет рендерить также и вьюшку input.rhtml чтобы можно было отредактировать текст, поэтому @supported_formats потребуются в обоих вьюшках, лучше добавить фильтр чем дублировать код.

    Осталось добавить выбор типа форматирования в input.rhtml:

    <code><%= select_tag :selected_format, options_for_select(@supported_formats, @selected_format) %></code>


    и написать preview.rhtml, я опять же не могу разместить код здесь (там есть div, и не важно что он внутри pre :).

    Страничка разбита на три блока:

    • preview – отображает отформатированный текст
    • source – форма с исходным текстом
    • formated_text – поле с отформатированным текстом


    Осталась одна маленькая деталь: получившиеся странички не “Well formed XHTML”, да и форма ввода текста кривовато выглядит. Нужно сделать чтобы браузер получал хорошо форматированные странички, т.е. нужен doctype, html, head, body, вобщем всё как положено, и причесать форму css’ом.

    Нам нужен шаблон страницы в который можно вставить результат рендеринга вьюшки, в рельсах это называется layout.
    Все что нужно сделать это добавить formatting.rhtml в app/views/layouts.

    Теперь чуть лучше скомпануем форму ввода – style.css и положим в public/stylesheets.

    Вот и всё на сегодня, первая часть закончена.



    Не судите строго, я очень давно не писал на русском, все больше на Ruby :)

    Наверняка из моего сумбурного описания не много понятно, просмотрев статью я понимаю что вопросов будет много. Например что такое form_for или options_for_select. Людям которым это действительно интерсно:

    • Если встретили незнакомое слово – зайдите на хороший сайт с документацией и наберите это слово в поиске
    • Если не знаете как что-то работает – читайте книгу о рельсах (она есть в emule) и задавайте вопросы


    Желающие посмотреть как выглядит текст размеченный markdown могут взглянуть на исходник статьи.

    Что может быть дальше?

    • Основное что я не затронул – это тесты, с них и начнем
    • Две странички слишком много для такого простого приложения, надо сократить до одной. Для этого нам понадобится познакомиться с AJAX и узнать как в рельсах работать с яваскриптом.
    • Я переживаю за сылки, я их все прощелкал и одна оказалась дохлая, больше щелкать мне уже не хочется, надо сделать чтоб не щелкать
    • А еще больше я переживаю за орфографию, подскажите какой сервис нормально может проверить орфографию, будет интересно прикрутить его к рельсам, если ещё не сделали =)
    • С появлением второй статьи хранить их исходники на рабочем столе станет обременительно (он и так захламлен :), так что надо будет сделать каталог статей. Заодно мы узнаем что такое REST и какое отношение он имеет к рельсам.
      Я заметил пост про AjaxScaffold без описания как им пользоваться, так что при желании можно сделать веб2нольный каталог на ActiveScaffold
    • Очень надеюсь что к этому моменту появятся соавторы и тогда мы познакомимся с тем, как организовать совместное редактирование статей. Узнаем как в рельсах осуществляется авторизация пользователей, как сделать статьи многоверсионными, как защититься от конкурентной записи.
    Share post
    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More
    Ads

    Comments 25

      +4
      Ну туториалов такого типа в сети навалом, поэтому не вижу смысла в такой статье, хотя конено если получится цикл статей то может чтонибудь из этого и выйдет.
        +2
        Это только проба пера, вспоминаю как писать на руссоком :)
        Цикл статей непременно получится, с русским пока беда, надо тренироваться.

        Текущая версия приложения это только идея использовать markdown/textile для хабра.
        Я покажу как идея может превратиться в полезный сервис. При этом будут затронуты задачи, типичные для любого веб приложения: как создать коллекцию ресурсов, как организовать общий доступ, как разграничить права, как использовать ajax, как тестировать и резворачивать приложение, как интегрировать с другими сайтами. Этого хватит на много статей, сейчас начинаю писать как создать коллекцию, и протестировать работу.
        0
        ну, насколько я знаю, textile поддерижвается по умолчанию, попоробуйте textilize()
          0
          Поддерживается, но для этого нужно установить gem. Он все правильно сделал :)
            0
            да нет же, вы можете посмотреть даже официальный скринкаст блога-за-15-минут, где Дэвид показывает, как пользоваться ей; эта функция поддерживается без всяких дополнительных gem`ов, как я понимаю.
              0
              по крайней мере, я ничего не устанавливал.
          +1
          Так нагляднее, видно что один гем отвечает за textile а другой за markdown.
          Важно и то, что у них одинаковый синтаксис, меня друзья часто спрашивают как можно писать на руби когда там нет интерфейсов. На самом деле интерфейсы всеже есть, только они не декларируются, принцип минимального удивления избавляет код от лишних слов.
          0
          Спасибо за еще одну статью о руби.
          Очень хочу начать изучать этот язык, но времени не хватает.
          А с такого рода статьями, да еще в одном месте, будет легче начать учить :)
            0
            Достаточно средне получилось. Поясню, что я имею в виду. Человек, который не имеет отношения к Руби и к рельсам в частности - особо ничего не поймет, думаю это недостаток статейного формата, тут более подойдет книга толковая и подробная. А человек, который с рельсами работал ничего нового не узнает.
              +1
              Да, я долго думал как сделать так чтобы было понятно и при этом достаточно компактно.
              Пришел к выводу что лучше выложить исходный код, дать ссылки на книги, доки и отвечать на вопросы.

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

              Человек работающий с рельсами возможно узнает что-то новое из седующих статей, а пока что надо обьяснить новичкам как сделать самые простые вещи.
              Я хотел ради интереса попробовать ActiveScaffold, но для нового человека это будет выглядеть примерно так: пишем в контроллере слово "scaffold" и получаем красивый интерфейс для управления коллекцией ресурсов. Это магия! и тогда придется все что происходит обьяснять на словах. Поэтому сейчас лучше писать чуть больше самого простого кода на руби и сэкономить кучу времени на словах.

              Я руководсвуюсь принципом KISS.
              В дальнейшем я прикручу фишечки и фенечки, интересные для продвинутых разработчиков (у самого руки чешутся:), но когда это будет естественным продолжением эволюции приложения, а пока нельзя.
              0
              А по-моему получилось очень даже ничего. Хотя, не знаю, как это выглядить для тех, кто совсем не знаком с рельсами. Но в одном я с вами согласен — невозможно написать всеобъемлющую статью на подобную тему, тут только книги + статьи имеют смысл. Вы правы, что не гонитесь за «объяснением всего, с нуля».

              А вообще интересно, что будет дальше. Для авторизации, версий и прочего собираетесь использовать плагины или руками?.. Ну и просто интересно посмотреть на ваш стиль программирования. Пока мне ну очень нравится стиль к которому стремятся ребята из The Rails Way.

              Так держать!.. ;)

              PS Если вам таки и вправду понадобится соавтор, можно попробовать со мной. Чукча вроде и не писатель, но все же:)
                0
                Соавтор мне действительно нужен. Потому и не гонюсь за обьяснением каждой строчки, да и не нужно это.

                Что такое руками? Если писать все самому, то это уже не Agile и совсем не Ruby way :)

                The Rails Way понравился, коротко и по делу.
                  0
                  Ну да.. Руками не тема, даже в образовательных целях, как я изначально предполагал.. ;)

                  А насчет участия в написании статей — мыло xabk*at*xabk.net, аська: 276548555. Временно я в инете только с работы, то есть с ~10 до 18 по Москве.

                  И вот еще, вспомнил, есть такая классная книга «Ruby for Rails: Ruby Techniques for Rails Developers» — если интересно и самому лень искать PDF-версию могу скинуть (кажется, она у меня на англицком, но ведь это не проблема?). Я бы советовал ее читать после Programming Ruby и Agile Web Development with RoR.
                    0
                    Книжка хорошая, надо дать линку в статье.
                      0
                      такие линки давать нельзя %)
                0
                Спасибо.
                Полезная статья.
                Чем больше статей на русском - тем лучше :)
                • UFO just landed and posted this here
                    0
                    Задумка статей в том, чтобы показать как идею можно превратить в реальное приложение с помощью рельсов. И тем самым сподвигнуть хотябы одного человека изучать Ruby, это будет очень хорошо.
                    0
                    Был бы я новайсом у меня были бы следующие вопросы:
                    Как обратиться к параметрам пришедшим к скрипту. Если через params то как отличить пост от гет
                    Как вывести какую либо переменную на екране
                    Как отлаживаться
                    Как работать с сессий и куками)

                    Кстати один из способов научиться писать на ruby - это начать на нем писать программки, если придумать себе задание сложно, то можно порешать задачки, например на acm.mipt.ru спортивные задачки можно сдавать на руби, я так его и освоил).
                    • UFO just landed and posted this here
                        0
                        Дублировать книги не хочется, а отличать POST от GET лучше в роутинге :)

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

                        Поработать с сессией еще предстоит, а вот как работать с куками достаточно странный вопросы для новичка, для чего ему это? :)
                        0
                        большое спасибо за статью! :)
                          0
                          Хочу поделиться впечатлениями от прохождения данного ЦУ:

                          Строчка:
                          $>gem install redcloth maruku

                          Должна быть подкреплена строчками:
                          apt-get install gcc ruby-dev1.8
                          и немного изменена:
                          $>gem install RedCloth maruku (регистр оказался важен))))

                          Все это актуально для дебиана.
                          Сорри, если это всем и так понятно, но у меня, как абсолютного нуба в руби и рельсах выяснения причин заняло около часа. Надеюсь, таким же как я поможет.

                          Only users with full accounts can post comments. Log in, please.