Журнал LinuxFormat - перейти на главную

LXF108:Rails

Материал из Linuxformat
Версия от 12:47, 23 августа 2009; Yaleks (обсуждение | вклад)

(разн.) ← Предыдущая | Текущая версия (разн.) | Следующая → (разн.)
Перейти к: навигация, поиск

Содержание

Rails: Создаем фотоальбом

Страшитесь C? Путаетесь в Perl? Пусть Алекс Янг покажет вам, как просто и быстро начать программировать на Ruby.

С момента своего создания фотогалерея Flickr поразительно разрослась. Она полностью изменила наши представления о хранении снимков в Интернете, а через ее каталоги каждый посетитель мог достаточно просто найти самые интересные фотографии. Но как ни хороша Flickr, разве не здорово иметь на своем сайте личную фотогалерею? Можно реализовать те возможности, которые нужны именно вам, и даже поделиться кодом с друзьями, чтобы они тоже создали себе нечто подобное.

Для написания классной, продвинутой галереи мы воспользуемся Ruby on Rails. Rails избавляет вас от мучений, присущих обычной web-разработке – можете забыть о мороке с SQL и XML; Rails предоставляет простые и удобные для восприятия абстракции через дружелюбный к программисту код Ruby. Его легко установить – потребуются лишь база данных и web-сервер; и web-разработка упрощается, благодаря наличию готовой структуры для каждого приложения.

Rails испытывает влияние популярных методологий: Не Повторяй Самого Себя (Don’t Repeat Yourself – DRY) и Разработка Через Тестирование (Test Driven Development – TDD). DRY предполагает, что код не должен дублироваться, и это уменьшает общую сложность проекта. TDD часто практикуется профессиональными Rails-разработчиками: данный метод подразумевает тестирование кода до его завершения. Написание тестов до того, как написано само приложение, часто способствует разработке более API-подобного кода с более ясной инкапсуляцией.

Мы рассмотрим некоторые технологии, используемые Rails-разработчиками в реальных проектах:

  • Установим Ruby on Rails с библиотеками и модулями расширения для обработки изображений.
  • Создадим фотогалерею с миниатюрами и возможностью управления пользователями.
  • Ознакомимся с основными компонентами каркаса Rails.

Часть 1 Устанавливаем Rails

Первая установка Rails кажется сложнее, чем она есть на самом деле – ведь познакомиться придется всего лишь с несколькими технологиями (если вы уже не программист Ruby!). Чтобы установить Rails, отвечающий потребностям нашего проекта, потребуются пять компонентов:

  • Ruby.
  • RubyGems.
  • Ruby on Rails: http://rubyonrails.org.
  • Реляционная СУБД – MySQL, PostgreSQL, SQLite (сегодня мы будем пользоваться SQLite).
  • Прочие библиотеки для обработки изображений и работы с Rails.

Минут через 15 все должно быть готово к написанию кода.

Для начала нужно проверить, установлен ли Ruby: команда which ruby выведет путь к интерпретатору. Если его у вас нет, понадобится пакет Ruby, и он есть в большинстве дистрибутивов Linux. В Debian и Ubuntu Ruby можно установить с помощью команды

sudo apt-get install ruby1.8

Желаете собрать Ruby из исходников? Загрузите их с сайта http://www.rubylang.org/en. Затем вам понадобится RubyGems – менеджер пакетов, с помощью которого можно устанавливать, удалять и обновлять библиотеки Ruby. В большинстве дистрибутивов Linux есть пакет для RubyGems: например, в Debian и Ubuntu это libgems-ruby1.8. Однако на момент написания статьи пакеты в этих дистрибутивах сильно устарели и не будут корректно работать с Rails 2, поэтому лучше установите Gems из исходных текстов.

Загрузите архив с сайта http://www.rubygems.org и распакуйте его, а затем запустите из получившегося каталога следующую команду:

sudo ruby setup.rb

Она установит команду gem1.8 и связанные с ней библиотеки.

После установки RubyGems добавление Rails – сущий пустяк. Следующая команда инсталлирует все необходимые библиотеки Ruby, а также утилиты командной строки Rails:

sudo gem1.8 install rails rake

Для хранения данных моделей Rails также необходима реляционная БД. Если вам кажется, что сервер СУБД на рабочем столе – излишество, есть прекрасная альтернатива для локальной разработки – SQLite (http://www.sqlite.org). Удостоверьтесь, что установлены как SQLite, так и ее библиотеки для разработчиков. Для этого выполните команды:

sudo apt-get install sqlite3
sudo apt-get install libsqlite3-dev
sudo gem1.8 install sqlite3-ruby

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

Теперь давайте проверим, что Rails установлен корректно. Чтобы начать проект Rails, просто наберите rails gallery – при этом будут созданы все необходимые каталоги и файлы конфигурации:

rails gallery
cd gallery
script/server

Последняя строка запускает web-сервер на Ruby, его можно использовать при разработке проекта. Откройте запущенный проект в браузере (http://localhost:3000). Вы должны увидеть страницу приглашения Rails. Пусть она висит в фоне, пока вы заняты этим уроком. Согласно настройкам БД по умолчанию, в подкаталоге db/ каталога проекта будет автоматически создана база данных SQLite3. Если вы хотите использовать вместо нее MySQL или Postgres, отредактируйте файл config/database.yml, указав в нем настройки своей БД. Убедитесь, что переменная adapter установлена в mysql или postgresql.

Наконец, фотогалерея будет бесполезной, если в ней не будет базовых возможностей обработки изображений. Для создания высококачественных миниатюр, воспользуемся библиотеками Rails ImageMagick и RMagick:

sudo apt-get install libmagick9-dev
sudo gem install rmagick

Часть 2 Приступаем к делу

Теперь пора показать, какая это стоящая и простая штука – разработка с Rails. Rails содержит средства генерации скелетных файлов, позволяющих создавать полнофункциональные приложения, а также поддерживает модули расширения. Мы воспользуемся и тем, и другим, чтобы написать галерею быстрее, чем разработчик на C# загрузит Visual Studio.

Если бы я сел и написал набор утилит для управления пользователями, у меня бы вышло нечто очень похожее на модуль Restful Authentication Рика Олсона [Rick Olson] – ну так сэкономим время и усилия и сразу возьмем его. Из подкаталога gallery/ каталога проекта выполните команды:

script/plugin source http://svn.techno-weenie.net/projects/plugins
script/plugin install restful_authentication
script/generate authenticated user sessions

Модуль Restful Authentication предоставляет: модель БД для пользователя; миграции БД для создания пользователя; контроллеры пользователя и сессии для обработки создания учетной записи, вход в систему и запоминание пользователя в cookies.

Модули устанавливаются в подкаталог vendor/plugins/ каталога проекта. Данный конкретный экземпляр также добавляет файлы в код проекта в каталоге app/ с помощью генератора.

Теперь откроем файл app/models/user.rb и рассмотрим код модуля. Он представляет несколько общеупотребимых технологий для управления объектами ActiveRecord. ActiveRecord – одна из основных частей каркаса: она отображает объекты Ruby на базу данных.

Даже с небольшим опытом в Ruby или его полным отсутствием вы должны понять следующий код:

validates_presence_of :login, :email
before_save :encrypt_password

Эти строки – на самом деле методы, которые выглядят как макросы; это общепринятый стиль в Rails. С помощью методов validates_ легко проверить поля перед их сохранением в базе данных. Метод before_save реализует жизненный цикл объекта – он позволяет вам выполнять свой собственный код при сохранении данных в базе. Здесь перед записью модели в БД будет вызван метод encrypt_password.

Прежде чем продолжить, запустите процедуру миграции, полученную от модуля:

rake db:migrate

Она выведет некоторые данные о таблице:

1 CreateUsers: migrating
-- create_table(“users”, {:force=>true})
-> 0.0044s
1 CreateUsers: migrated (0.0046s)

Добавим пользователя и зайдем

Но как нам воспользоваться тем, что мы успели добавить? К счастью, модуль Restful Authentication установил контроллер, поддерживающий создание пользователя. Контроллеры – другая важная часть Rails: здесь они известны как ActionControllers и находятся между HTML-шаблонами и моделями ActiveRecord.

Чтобы добавить пользователя, зайдите на http://localhost:3000/users/new в своем браузере и введите необходимые данные. Затем укажите выбранное вами имя на http://localhost:3000/sessions/new. Вы будете отосланы на страницу шаблона Rails, но после добавления фотографий мы это исправим. Выполните команду:

script/generate scaffold photo title:string description:text filename:
string content_type:string size:integer user_id:integer width:
integer height:integer parent_id:integer path:string thumbnail:string
rake db:migrate

Будут добавлены: модель Photo; таблица в БД для фотографий с ID (создается автоматически) и набором необходимых полей; контроллер PhotosController с действиями по просмотру, созданию, обновлению и удалению фотографий; и сопутствующие представления (виды). Чтобы взглянуть на результаты, откройте адрес http://localhost:3000/photos. Хотя это и работает, но выглядит не очень. Опять же и контроллер пользователя не сочетается с сайтом. Давайте решим эти проблемы…

Добавляем стиль

Генератор каркаса создал файл app/views/layouts/photos.html.erb. В директории раскладок сайта находятся различные HTML-шаблоны. Используйте только один для вашего приложения, и он будет разделен между контроллерами.

Все контроллеры по умолчанию используют шаблон application. html.erb, если не задано иное, поэтому переименуйте photos.html.erb в application.html.erb, откройте его и измените содержимое тэга <title> на что-нибудь более общее. Открыв http://localhost:3000/users в своем браузере, вы увидите пользовательские шаблоны с application.html.erb.

Теперь нужно лишь задать индексную страницу сайта. Используем в качестве нее список фотографий. Удалите файл public/index.html, который был установлен Rails, и добавьте следующую строку в файл config/routes.rb:

map.connect ‘’, :controller => ‘photos’

Rails предоставляет все, что нужно для обработки загрузки файлов. Однако вместо реализации ее в PhotosController (сокращение контроллера и повторное использование кода в моделях – хорошая практика), можно поместить большую часть в модель Photo. Так как все загрузки файлов обрабатываются в общем-то одинаково, для добавления в модель необходимого функционала можно воспользоваться модулем расширения. Установите модуль attachment_fu:

script/plugin install attachment_fu

Теперь откройте модель Post (app/models/post.rb) и настройте его:

class Photo < ActiveRecord::Base
has_attachment :storage => :file_system,
:thumbnails => { :thumb => ‘160>’ },
:content_type => :image
validates_as_attachment
end

Открыв модель Photo, добавьте следующую строку:

belongs_to :user

Будет установлена связь между фотографиями и пользователями. Также можно добавить has_many :photos в модель User.

Просмотр фотографий

Перед тестированием нужно исправить виды ‘photo edit’ и ‘new’, активировав в них загрузку файлов. Откройте views/photos/edit.html.erb и views/photos/new.html.erb и измените определение формы на следующее (это просто стенографическая запись Rails для HTML-кода):

<% form_for(@photo, :html => { :multipart => true }) do |f| %>

Некоторые из полей, созданных генератором, не подходят для наших форм. Уберите все поля после Description в обоих шаблонах – просто удалите целый блок для каждого поля, включая тэг параграфа. Наконец, добавьте поле загрузки файла:

<p>
<b>Photo</b><br />
<%= f.file_field :uploaded_data %>
</p>

Теперь нужно изменить индексную страницу, содержащую список фотографий – так, чтобы на ней показывались миниатюры. Замените весь файл строкой:

render :partial => ‘photo’, :collection => @photos %>

Эта строка выводит ‘partial’ (так называются повторно используемые шаблоны) для каждой фотографии в массиве @photos. Контроллер PhotosController загружает @photos в действии для индексной страницы. Добавить partial для фотографий просто: создайте файл app/views/photos/_photo.html.erb и добавьте в него строки:

<div class=”photo”>
<h2>
<%= h photo.title %> <%= link_to ‘Edit’, edit_photo_path(photo) %>
<%= link_to ‘Delete’, photo, :confirm => ‘Are you sure?’, :method =>
:delete %>
</h2>
<%= link_to image_tag(photo.public_filename(:thumb)), photo %>
<%= textilize h(truncate(photo.description)) %>
</div>

Некоторые из вызовов этих методов – помощники, предоставляемые Rails и библиотеками, которые он использует. Например, h() гарантирует, что текст безопасен и не содержит HTML-кода – это хороший способ «провести санобработку» отправляемого пользователем контента. Метод textilize выводит текст в соответствии с требованиями Textile.

Также можно отредактировать файл app/views/photos/show.html. erb, удалив ненужные поля. Я убрал заголовок (‘title’), переместил ссылки «редактировать/назад» в верхнюю часть файла и добавил тэг image для фотографии:

<h2><%=h @photo.title %></h2>
<%= link_to ‘Edit’, edit_photo_path(@photo) %> |
<%= link_to ‘Back’, photos_path %>
<div class=”large_photo”><%= image_tag @photo.public_filename %></div>

Теперь измените основной шаблон (app/views/layouts/application. html.erb), исправив строку stylesheet_link_tag на…

<%= stylesheet_link_tag :all %>

…и добавив некую общую навигацию над выражением yield:

<div id=”navigation”>
<% if current_user %>
<%= link_to ‘Logout’, session_url, :method => ‘delete’ %> |
<% else %>
<%= link_to ‘Login’, new_session_url %> | <%= link_to ‘Register’, new_user_url %> |
<% end %>
<%= link_to ‘All Photos’, photos_url %> | <%= link_to ‘New Photo’, new_photo_path %>
</div>

Вы будете часто использовать link_to. Он создает ссылки на основе файла config/routes.rb, гарантируя, что URL-адреса будут выглядеть именно так, как вы хотите, и позволяя вам забыть о том, как они пишутся. Если вы видите метод, который заканчивается на _url или _path, знайте, что это ссылка на путь. Например, photos_url и photos_path оба вернут /photos.

Контроллер ApplicationController определяется в файле app/controllers/application.rb и наследует от ActionController::Base. Это действие, которое по умолчанию визуализирует шаблон app/views/photos/index.erb.html. PhotosController доступен по адресу http://localhost:3000/ photos. Чтобы миниатюры не выводились на индексной странице, контроллер нужно изменить. Отредактируйте файл app/controllers/photos_controller.rb так, чтобы вывод индекса игнорировал миниатюры, где-то в строке 5:

@photos = Photo.find(:all, :conditions => ‘thumbnail is NULL’)

Перед отправкой фотографий также нужно убедиться в том, что пользователь зашел в систему. Удалите следующие строки из UsersController и добавьте их в app/controllers/application.rb:

# Be sure to include AuthenticationSystem in Application
# Controller instead
include AuthenticatedSystem

Теперь нужно удостовериться, что при создании пользователя устанавливается его ID. Замените первую строку действия create в PhotosController:

@photo = current_user.photos.new params[:photo]

и измените первую строку действия update:

@photo = current_user.photos.find params[:id]

Как видите, здесь, для гарантии того, что пользователь может редактировать только свои фотографии, используется связь Photos с моделью User. Нужно сделать еще кое-что: убедиться, что только пользователи, зашедшие в систему, могут создавать и редактировать фотографии. Это можно сделать с помощью модуля Restful Authentication. Добавьте такую строку над выводом индекса в PhotosController:

before_filter :login_required, :only => [ :edit, :update, :new, :create ]

Стили фотографий

Таблицы стилей хранятся в каталоге public/stylesheets. Добавьте туда файл screen.css:

#navigation { background-color: #000; padding: 4px; margin: 0; color:
#aaa; }
#navigation a { color: #fff; text-decoration: none; }
#navigation a:hover { background-color: #fff; color: #000; }
.photo { width: 30%; float: left; background-color: #f0f0f0; margin:
10px 10px 0 0; padding: 10px; height: 220px; }
.photo h2 { margin: 0 0 14px 0; padding: 0; font-size: 1.5em; }
.large_photo { margin: 10px 0; }

Остановите script/server на своем терминале, нажав Ctrl+C. Теперь снова запустите его, и attachment-fu будет готов к использованию в вашей фотогалерее.

После добавления модулей в проект нужно перегрузить процесс web-сервера; то же относится к изменению файлов конфигурации Rails, включая config/environment.rb. К счастью, остальной код и config/routes.rb редактируются динамически.

Теперь можно кликнуть по ссылке Register для создания пользователя и зайти в систему. Помните, что при этом используется имя, а не адрес электронной почты. Кликните по ссылке New Photo для загрузки фотографии в коллекцию. Теперь используйте сэкономленное время: загрузите свои отпускные снимки!

Персональные инструменты
купить
подписаться
Яндекс.Метрика