В продолжении статьи ”Первое знакомство с Ruby on Rails” мы научимся работать с базой данных, и создадим каталог статей.
Узнаем как написать плагин, попробуем использовать AJAX и рассмотрим некоторые проблемы при развёртывании приложения на хостинге.
Я работаю с MySQL, поэтому примеры установки будут для неё.
Пользователям Windows нужно скачать и установить MySQL-5.0.
Пользователям Linux (Ubuntu) еще проще:
После установки проверим что сервер работает:
Настало время создать нужные базы данных. Потребуется их две – одна для разработки и одна для тестирования:
Теперь давайте посмотрим на файл
Осталось протестировать соединение приложения с базой данных. Идём в папку с приложением и набираем
Если появляются сообщения об ошибках, значит где-то вы ошиблись в настройках соединения, проверьте их.
Связь объектов и баз данных в рельсах осуществляется с помощью OR меппера, который называется ActiveRecord. Он занимается отображением полей из таблицы БД в поля объекта, валидацией объектов перед сохранением, генерацией кода для представления связей между объектами.
Чтобы создать новую модель достаточно наследоваться от класса
По умолчанию ActiveRecord будет работать с таблицей названной также как класс, только во множественном числе. В нашем случае Articles.
Ко всем полям таблицы можно получить доступ с помощью методов с тем же названием:
ActiveRecord наглядно демонстрирует суть принципа “Convention over Configuration” – не требуется писать код для того, чтобы программа заработала, код нужен только когда программа должна работать не как обычно. Например:
ActiveRecord предоставляет много полезных функций, вот некоторые из них:
Что бы посмотреть документацию по ActiveRecord и другим установленным гемам нужно запустить
и открыть в браузере
http://localhost:8808/
Мы будем использовать
Я не буду включать в текст исходный код, чтобы не раздувать статью, его можно посмотреть online, я буду описывать для чего нужны различные куски кода.
Рельсы сгенерировали несколько файлов, посмотрим на некоторые из них:
С моделью думаю всё понятно, посмотрим на контроллер. У контроллера есть 7 методов:
Строчка
PUT и DELETE это методы HTTP, как GET и POST.
Таким образом получилось уместить все необходимые для управления коллекцией методы в небольшой и понятный для пользователя набор урлов.
Принцип разбиения приложения на наборы ресурсов и предоставления универсального формата доступа к ресурсам (способа построения урлов) называется REST. Идея в том, чтобы использовать для работы с ресурсами протокол без состояния (вся необходимая информация содержится в урле), что улучшит масштабируемость приложения и упростит кеширование.
Поскольку ресурс однозначно идентифицируется урлом, основная работа приложения сводится к двум задачам – отдавать пользователю странички с указанным в урле ресурсом и проверять права доступа если ресурс не общедоступный. Поэтому писать и сопровождать веб приложения в стиле REST очень просто.
Посмотрим на результат, запускаем сервер
и идем
http://localhost:3000/articles
Я получил вот такую ошибку:
В базе данных нет таблицы
Изменения таблиц БД в рельсах делаются через механизм миграций. Одну миграцию рельсы сгенерировали для нас – создание таблицы
В результате миграции в базе данных была создана таблица articles, и теперь мы можем нажать в браузере F5 и поиграть с приложением.
Rake это замена утилит типа
Чтобы узнать что Rake может сделать для нас выполним следующее:
Получим длинный список задач, которые Rake умеет делать. Задачи пишутся на Ruby и находятся в файле Rakefile. Изначально файл содержит только стандартный набор задач, которые подключаются с помощью
Прелесть Rake в том, что описание задачи это обычный код на Ruby. Это сильно упрощает добавление новых задач по сравнению с
У Мартина Фаулера есть отличная статья о Rake (на английском).
Будем знакомиться с Rake по мере необходимости. Сейчас нам уже известно что задача
В результате база мигрирует до нулевой версии, когда еще не было создано ни одной таблицы. Это удобный способ очистить базу после экспериментов с приложением. Потом можно снова вызвать
Надеюсь вы уже посмотрели на каталог и убедились в этом. Время заняться главной задачей приложения – форматированием статей.
У нас уже есть код для форматирования, теперь нужно понять как его использовать. В первой версии у нас был только контроллер, поэтому код располагался прямо в нем, теперь появилась модель
В рельсах это естественный путь добавления функциональности к приложению. При этом код форматирования будет отделен от модели, что позволит использовать его в других приложениях.
Хочется чтобы плагин обеспечил поддержку форматирования без лишних слов, например так:
При этом исходный текст находится в поле
Начнем. Прежде всего доверим рельсам создать для нас скелет плагина:
В папке
Теперь осталось написать код для форматирования и добавить поддержку в ActiveRecord.
Как это сделать? Задача сводится к тому, чтобы добавить метод
В Ruby все является обьектом, в этой простенькой программе
вызывается метод обьекта. У какого обьекта? Это объект типа модуль (аналог namespace, package), глобальный модуль называется Kernel. Модули похожи на классы, отличаются тем, что могут содержать только методы, константы и другие модули и классы. При этом руби позволяет подмешивать (mixin) модули в другие модули и классы, это делается с помощью методов
или
При этом в классе
Практически весь код плагина будет в файле
Плагин состоит из двух модулей:
Посмотрим что делает метод
Сначала узнаем какие форматы поддерживаются и какие поля будут использоваться (в нашем случае
Вся работа по форматированию происходит в модуле
Теперь в
и можно пробовать плагин в деле. Нужно поправить вьюшки, чтобы отображать отформатированный текст.
Прежде всего стоит избавиться от дублирования кода в new и edit формах и создать одну форму, которую можно использовать создания и редактирования статей. Единственное отличие форм – урл и метод отправки. Поэтому удобно сделать вспомогательный метод, который будет определять урл и метод в зависимости от того, как используется форма, для редактирования или для создания статьи.
Для вспомогательных методов рельсы создают модули-помощники (helpers), разместим код в
Теперь создадим вьюшку для формы. Повторно используемые куски вьюшек в рельсах называются partials. Названия файлов partials начинаются с подчёркивания. Обычно они находятся там же где вьюшки, которые их используют.
После такого рефакторинга код вьюшек
Осталось добавить preview. Для этого в контроллере создадим метод
Затем добавим правило в таблицу маршрутизации.
Вторая строчка добавляет правило для урла
Теперь добавим поддержку на форму. Чтобы не загромождать вьюшку кодом сделаем вспомогательный метод. Этот метод создаёт кнопку, при нажатии на которую форма асинхронно отправляется на сервер и ответ отображается в переданном в метод элементе. Остаётся добавить кнопку и элемент для отображения отформатированной статьи во вьюшку.
Поскольку кнопка preview использует библиотеку prototype для асинхронной отправки запросов на сервер, нужно добавить её загрузку в шаблон страницы.
На этом функциональность второй версии можно считать завершённой.
Теперь можно убрать код, оставшийся с первой версии.
И напоследок.
Может случиться так, что дома у вас все работает, а на хостинге категорически отказывается. Причин может быть много, но наиболее частая из них – не хватает каких-то гемов, или у хостера они не той версии. Это касается как самих рельсов, так и гемов, от которых зависит ваше приложение.
Сначала разберемся с зависимостью от рельсов. Перед тем как заливать ваше приложение на хостинг очень полезно сделать следующее:
В результате в папке
Помимо рельсов, приложение часто зависит еще от каких-то гемов, в нашем слечае это RedCloth и Maruku. Для решения проблем с этими зависимостями Dr Nic написал замечательный плагин – Gems on Rails. Работает он по такому же принципу – делает локальные копии гемов. Давайте его установим и научимся использовать:
Идем в папку с приложением и запускаем
Теперь у нас установлен плагин Gems on Rails, который добавил полезные задачи для Rake.
Давайте сделаем локалные копии гемов, нужных нашему приложению:
У меня в папке
На этом все. Задавайте вопросы, читайте документацию и книгу о рельсах.
PS. Пока писал последние строчки наткнулся на интересный сайт со скринкастами о рельсах.
Узнаем как написать плагин, попробуем использовать AJAX и рассмотрим некоторые проблемы при развёртывании приложения на хостинге.
Начнем с базы данных.
Я работаю с MySQL, поэтому примеры установки будут для неё.
Пользователям Windows нужно скачать и установить MySQL-5.0.
Пользователям Linux (Ubuntu) еще проще:
<code class='sh' lang='sh'>$>sudo apt-get install mysql-server-5.0 libmysql-ruby</code>
После установки проверим что сервер работает:
<code class='sh' lang='sh'>$>mysqladmin ping -u root mysqld is alive</code>
Настало время создать нужные базы данных. Потребуется их две – одна для разработки и одна для тестирования:
<code class='sh' lang='sh'>$>mysqladmin create example_development -u root $>mysqladmin create example_test -u root</code>
Теперь давайте посмотрим на файл
config/database.yml
. Тут находятся параметры соединения с базой данных. Обычно ничего менять не требуется, по умолчанию mysql создаёт пользователя root со всеми правами и без пароля.Осталось протестировать соединение приложения с базой данных. Идём в папку с приложением и набираем
<code class='sh' lang='sh'>$>rake</code>
Если появляются сообщения об ошибках, значит где-то вы ошиблись в настройках соединения, проверьте их.
Введение в работу с БД.
Связь объектов и баз данных в рельсах осуществляется с помощью OR меппера, который называется ActiveRecord. Он занимается отображением полей из таблицы БД в поля объекта, валидацией объектов перед сохранением, генерацией кода для представления связей между объектами.
Чтобы создать новую модель достаточно наследоваться от класса
ActiveRecord::Base
<code class='ruby' lang='ruby'>class Article < ActiveRecord::Base end</code>
По умолчанию ActiveRecord будет работать с таблицей названной также как класс, только во множественном числе. В нашем случае Articles.
Ко всем полям таблицы можно получить доступ с помощью методов с тем же названием:
<code class='ruby' lang='ruby'>#Пусть в таблице Articles есть поле title Article.create(:title => 'Hello World!') article = Article.find(1) print article.title #=> Hello World!</code>
ActiveRecord наглядно демонстрирует суть принципа “Convention over Configuration” – не требуется писать код для того, чтобы программа заработала, код нужен только когда программа должна работать не как обычно. Например:
- нужно использовать таблицу с другим именем – добавляем в класс строчку
set_table_name "mytablename"
- в таблице криво названы поля – пожалуй лучше написать для полей методы доступа с нормальными названиями
- один объект отображается на несколько таблиц – придётся писать свой ORM :)
ActiveRecord предоставляет много полезных функций, вот некоторые из них:
Article.find(id)
– найти статью по id (PrimaryKey в БД, обычно это Integer)Article.find(:all)
– выбрать все статьиArticle.find_by_title('Hello World!')
– найти статью с заголовком “Hello World!”Article.create(:title => 'Hello World!')
– создать статью и сохранить в БДarticle.update(:title => 'Goodbye World!')
– обновить статью в БДarticle.destroy
– удалить статью из БД
Что бы посмотреть документацию по ActiveRecord и другим установленным гемам нужно запустить
<code class='sh' lang='sh'>`$>gem_server`</code>
и открыть в браузере
http://localhost:8808/
Теперь давайте попробуем создать каталог.
Мы будем использовать
script/generate
чтобы создать модель, контроллер и вьюшки для каталога.<code>$>ruby script/generate scaffold_resource article title:string body_format:string body:text</code>
Я не буду включать в текст исходный код, чтобы не раздувать статью, его можно посмотреть online, я буду описывать для чего нужны различные куски кода.
Рельсы сгенерировали несколько файлов, посмотрим на некоторые из них:
app/models/article.rb
– модель для статьиapp/controllers/articles\_controller.rb
– контроллер для управления каталогом статейconfig/routes.rb
– добавлена строчкаmap.resources :articles
app/views/articles/...
– вьюшки для создания, редактирования и просмотра статейapp/views/layouts/articles.rhtml
– шаблон страниц для работы к каталогомdb/migrate/001_create_articles.rb
– создание таблицы для статей в базе данных
С моделью думаю всё понятно, посмотрим на контроллер. У контроллера есть 7 методов:
index
– страница отображает всю коллекцию статейshow
– страница отображает одну статьюnew
– страница для создания новой статьиedit
– страница для редактирования существующей статьиcreate
– обработчик поста формы создания новой статьиupdate
– обработчик поста формы редактирования статьиdestroy
– обработчик запроса удаления статьи
Строчка
map.resources :articles
в файле config/routes.rb
добавляет нужные правила маршрутизации урлов. Вот как выглядят созданные урлы:/articles (GET)
– index/articles/:id (GET)
– show (:id – идентификатор статьи)/articles;new (GET)
– new/articles/:id;edit (GET)
– edit/articles (POST)
– create/articles/:id (PUT)
– update/articles/:id (DELETE)
– destroy
PUT и DELETE это методы HTTP, как GET и POST.
Таким образом получилось уместить все необходимые для управления коллекцией методы в небольшой и понятный для пользователя набор урлов.
Принцип разбиения приложения на наборы ресурсов и предоставления универсального формата доступа к ресурсам (способа построения урлов) называется REST. Идея в том, чтобы использовать для работы с ресурсами протокол без состояния (вся необходимая информация содержится в урле), что улучшит масштабируемость приложения и упростит кеширование.
Поскольку ресурс однозначно идентифицируется урлом, основная работа приложения сводится к двум задачам – отдавать пользователю странички с указанным в урле ресурсом и проверять права доступа если ресурс не общедоступный. Поэтому писать и сопровождать веб приложения в стиле REST очень просто.
Посмотрим на результат, запускаем сервер
<code class='sh' lang='sh'>`$>ruby script/server` </code>
и идем
http://localhost:3000/articles
Я получил вот такую ошибку:
<code>Mysql::Error: Table 'example_development.articles' doesn't exist: SELECT * FROM articles</code>
В базе данных нет таблицы
articles
, надо бы её создать.Изменения таблиц БД в рельсах делаются через механизм миграций. Одну миграцию рельсы сгенерировали для нас – создание таблицы
articles
(db/migrate/001_create_articles.rb
). Нужно применить её к базе данных, идём в папку с приложением и запускаем<code>$>rake db:migrate</code>
В результате миграции в базе данных была создана таблица articles, и теперь мы можем нажать в браузере F5 и поиграть с приложением.
Несколько слов о Rake.
Rake это замена утилит типа
make
, ant
, maven
.Чтобы узнать что Rake может сделать для нас выполним следующее:
<code class='sh' lang='sh'>$>rake -T</code>
Получим длинный список задач, которые Rake умеет делать. Задачи пишутся на Ruby и находятся в файле Rakefile. Изначально файл содержит только стандартный набор задач, которые подключаются с помощью
require 'tasks/rails'
. Вот так например выглядит описание задачи db:migrate
:<code class='ruby' lang='ruby'>desc "Migrate the database through scripts in db/migrate. Target specific version with VERSION=x" task :migrate => :environment do ActiveRecord::Migrator.migrate("db/migrate/", ENV["VERSION"] ? ENV["VERSION"].to_i : nil) Rake::Task["db:schema:dump"].invoke if ActiveRecord::Base.schema_format == :ruby end</code>
Прелесть Rake в том, что описание задачи это обычный код на Ruby. Это сильно упрощает добавление новых задач по сравнению с
ant
или maven
.У Мартина Фаулера есть отличная статья о Rake (на английском).
Будем знакомиться с Rake по мере необходимости. Сейчас нам уже известно что задача
db:migrate
запускает миграции, при чем можно как применять так и откатывать изменения. Если мы посмотрим в файлик db/migrate/001_create_articles.rb
, то увидим что у класса CreateArticles
есть два метода: up и down. Эти методы вызываются когда миграция применяется и откатывается соответственно. Цифры 001
в названии файла это порядковый номер миграции, он используется для определения очерёдности применения миграций, при этом рельсы хранят в базе данных её версию, чтобы не применять одну миграцию несколько раз. Чтобы мигрировать базу до определенной версии нужно запустить db:migrate
с параметром VERSION:<code>$>rake db:migrate VERSION=0</code>
В результате база мигрирует до нулевой версии, когда еще не было создано ни одной таблицы. Это удобный способ очистить базу после экспериментов с приложением. Потом можно снова вызвать
db:migrate
без параметров, в итоге будут применены все миграции.Каталог это здорово, но статьи не форматируются.
Надеюсь вы уже посмотрели на каталог и убедились в этом. Время заняться главной задачей приложения – форматированием статей.
У нас уже есть код для форматирования, теперь нужно понять как его использовать. В первой версии у нас был только контроллер, поэтому код располагался прямо в нем, теперь появилась модель
Article
, но если мы расположим код в модели, то жестко свяжем форматирование с конкретной моделью, а это приведет к тому, что мы не сможем повторно использовать код, хотя он никак не зависит от модели которую будет форматировать.Будем писать плагин.
В рельсах это естественный путь добавления функциональности к приложению. При этом код форматирования будет отделен от модели, что позволит использовать его в других приложениях.
Хочется чтобы плагин обеспечил поддержку форматирования без лишних слов, например так:
<code>class Article < ActiveRecord::Base acts_as_formatted :body end</code>
При этом исходный текст находится в поле
body
, а отформатированиый текст статьи можно получить с помощью метода body_as_html
. Формат, в котором написана статья, находится в поле body_format
.Начнем. Прежде всего доверим рельсам создать для нас скелет плагина:
<code>$>ruby script/generate plugin acts_as_formatted</code>
В папке
vendor/plugins
появился наш плагин. Что внутри:lib
– в этой папке размещается кодlib/acts_as_formatted.rb
– тут будет код плагинаtasks
– плагин может добавлять задачи для Rake, они появятся в общем спискеtest
– плагин должен быть хорошо протестированinit.rb
– этот файл выполняется при загрузке, отсюда включаются файлы плагина, которые лежат вlib
install.rb
,uninstall.rb
– эти файлы выполняются при установке и удалении плагина, нам они не потребуютсяRakefile
– файл с задачами Rake для плагина (запуск тестов и генерация документации)
Теперь осталось написать код для форматирования и добавить поддержку в ActiveRecord.
Как это сделать? Задача сводится к тому, чтобы добавить метод
acts_as_formatted
к ActiveRecord::Base
. А в этом методе сгенерировать код, необходимый для поддержки форматирования. Для этого нам понадобится знать как это можно сделать в Ruby.Как в Ruby добавить функциональность к существующему классу.
В Ruby все является обьектом, в этой простенькой программе
<code class='ruby' lang='ruby'>print "Hello World!"</code>
вызывается метод обьекта. У какого обьекта? Это объект типа модуль (аналог namespace, package), глобальный модуль называется Kernel. Модули похожи на классы, отличаются тем, что могут содержать только методы, константы и другие модули и классы. При этом руби позволяет подмешивать (mixin) модули в другие модули и классы, это делается с помощью методов
extend
и include
у модулей и классов, например:<code class='ruby' lang='ruby'>class MyClass extend Enumerable end</code>
или
<code class='ruby' lang='ruby'>class MyClass end MyClass.extend(Enumerable)</code>
При этом в классе
MyClass
появятся все методы, константы, классы и модули, определенные в модуле Enumerable
.Пишем плагин.
Практически весь код плагина будет в файле
acts_as_formatted.rb
.Плагин состоит из двух модулей:
ActiveRecord::Acts::ActsAsFormatted::Formatting
– код отвечающий за форматированиеActiveRecord::Acts::ActsAsFormatted::ClassMethods
– единственный в нем метод –acts_as_formatted
, этот модуль добавим кActiveRecord::Base
Посмотрим что делает метод
acts_as_formatted
.Сначала узнаем какие форматы поддерживаются и какие поля будут использоваться (в нашем случае
body
, body_format
, body_as_html
), затем добавляем правило валидации, чтобы проверить что поле формата содержит допустимый формат (обьект невозможно сохранить если не прошла валидация), и добавляем классу два метода для получения поддерживаемых форматов и отформатированного поля (supported_formats
и body_as_html
).Вся работа по форматированию происходит в модуле
ActiveRecord::Acts::ActsAsFormatted::Formatting
. Здесь есть методы которые форматируют текст: format
, format_markdown
и format_textile
, и метод supported_formats
, который определяет поддерживаемые форматы, иcходя из методов, которые есть в модуле.Теперь в
init.rb
добавим код инициализации:<code class='ruby' lang='ruby'>require 'acts_as_formatted' ActiveRecord::Base.extend(ActiveRecord::Acts::ActsAsFormatted::ClassMethods)</code>
и можно пробовать плагин в деле. Нужно поправить вьюшки, чтобы отображать отформатированный текст.
Причешем вьюшки и сделаем preview
Прежде всего стоит избавиться от дублирования кода в new и edit формах и создать одну форму, которую можно использовать создания и редактирования статей. Единственное отличие форм – урл и метод отправки. Поэтому удобно сделать вспомогательный метод, который будет определять урл и метод в зависимости от того, как используется форма, для редактирования или для создания статьи.
Для вспомогательных методов рельсы создают модули-помощники (helpers), разместим код в
app/helpers/application_helper.rb
. Метод edit_form_for
определяет была ли модель уже сохранена и, в зависимости от этого, генерирует форму для создания или обновления модели. Методы submit_edit
и cancel_edit
создают кнопку для отправки формы и линку для возврата из формы.Теперь создадим вьюшку для формы. Повторно используемые куски вьюшек в рельсах называются partials. Названия файлов partials начинаются с подчёркивания. Обычно они находятся там же где вьюшки, которые их используют.
После такого рефакторинга код вьюшек
new
и edit
становится совсем простым и сводится к одной строчке:<code class='ruby' lang='ruby'><%= render :partial => 'article', :object => @article %></code>
Осталось добавить preview. Для этого в контроллере создадим метод
preview
, который будет возвращать отформатированный текст статьи.<code class='ruby' lang='ruby'>def preview article = Article.new(params[:article]) render_text article.body_as_html end</code>
Затем добавим правило в таблицу маршрутизации.
<code class='ruby' lang='ruby'>map.resources :articles, :collection => { :preview => :any }</code>
Вторая строчка добавляет правило для урла
/articles;preview
. :collection
означает что будет использоваться урл коллекции (/articles
), поскольку не важно для какой конкретно статьи генерируется preview. Вместо :collection
можно использовать :member
, тогда урл будет для конкретной статьи (/articles/:id
), в нашем случае это не позволит делать preview создаваемых статей. :any
означает что для вызова можно использовать любой HTTP метод, в нашем случае будут использоваться POST при создании и PUT при редактировании.Теперь добавим поддержку на форму. Чтобы не загромождать вьюшку кодом сделаем вспомогательный метод. Этот метод создаёт кнопку, при нажатии на которую форма асинхронно отправляется на сервер и ответ отображается в переданном в метод элементе. Остаётся добавить кнопку и элемент для отображения отформатированной статьи во вьюшку.
Поскольку кнопка preview использует библиотеку prototype для асинхронной отправки запросов на сервер, нужно добавить её загрузку в шаблон страницы.
<code class='ruby' lang='ruby'><%= javascript_include_tag 'prototype' %></code>
На этом функциональность второй версии можно считать завершённой.
Теперь можно убрать код, оставшийся с первой версии.
<code>script/destroy controller input preview</code>
И напоследок.
Немного об установке приложения у хостера.
Может случиться так, что дома у вас все работает, а на хостинге категорически отказывается. Причин может быть много, но наиболее частая из них – не хватает каких-то гемов, или у хостера они не той версии. Это касается как самих рельсов, так и гемов, от которых зависит ваше приложение.
Сначала разберемся с зависимостью от рельсов. Перед тем как заливать ваше приложение на хостинг очень полезно сделать следующее:
<code>$>rake rails:freeze:gems</code>
В результате в папке
vendor/rails
появится копия рельсов с которой вы разрабатываете ваше приложение, и сервер будет использовать её, так что беспокоиться о том, какая версия есть у хостера, больше не потребуется.Помимо рельсов, приложение часто зависит еще от каких-то гемов, в нашем слечае это RedCloth и Maruku. Для решения проблем с этими зависимостями Dr Nic написал замечательный плагин – Gems on Rails. Работает он по такому же принципу – делает локальные копии гемов. Давайте его установим и научимся использовать:
<code>$>gem install gemsonrails</code>
Идем в папку с приложением и запускаем
<code>$>gemsonrails Installed gems_on_rails 0.6.4 to ./vendor/plugins/gemsonrails</code>
Теперь у нас установлен плагин Gems on Rails, который добавил полезные задачи для Rake.
<code>$>rake -T ... rake gems:freeze # Freeze a RubyGem into this Rails application; init.rb will be loaded on startup. rake gems:link # Link a RubyGem into this Rails application; init.rb will be loaded on startup. rake gems:unfreeze # Unfreeze/unlink a RubyGem from this Rails application ...</code>
gems:link
– добавляет вvendor/gems
код, который загружает гем при загрузке приложения, если гема нет, то приложение не загрузится (удобно узнавать об отсутствии гемов сразу, а не во время работы)gems:freeze
– делает локальную копию гема, именно эта копия будет использоваться в приложенииgems:unfreeze
– удаляет локальную копию и код сгенерированныйgems:link
Давайте сделаем локалные копии гемов, нужных нашему приложению:
<code>$>rake gems:freeze GEM=maruku $>rake gems:freeze GEM=redcloth</code>
У меня в папке
vendor/gems
появились папки maruku-0.5.6
и RedCloth-3.0.4
.На этом все. Задавайте вопросы, читайте документацию и книгу о рельсах.
Главное пишите код!
PS. Пока писал последние строчки наткнулся на интересный сайт со скринкастами о рельсах.