Website за 20 минут на ruby

Этот пост скорее всего не пособие, а некая компиляция-рецепт на русском языке, как сделать простое и легкое web-приложение на руби. Итак, все началось со списка: 24 из 100, который я запостил в своем ЖЖ. Я опубликовал названия 24ех книг по мнению коллектива редакции «НГ-Ex libris», потрясли литературный мир и оказали влияние на всю культуру. Список любопытный, и в комментах развернулось обсуждение, что для себя такое составить интересно, но уж копипастить из окна в блокнот совсем лениво.

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

Для работы потребуется: ruby, gem, vim
Начнем классически, в окне терминала набираем:


$ ruby -v
ruby 1.8.7
$ gem -v
1.3.3

Далее все еще проще:

$ gem install rake sinatra activerecord mongrel sqlite3-ruby

Если нужно использовать другую базу данных – вперед, все в ваших руках. Я использовал sqlite потому как забыл root пароль к mysql, а будить админа его спрашивать решил не существенным. Пока процесс жужжит, в другом окне терминала можно начать описывать шаблон приложения.

$ vim empty.rb

Содержимое файла простое и предсказуемое:


require 'rubygems'			# Наши гемы
require 'sinatra'			# Наш framework
require 'activerecord'		# Наша связь с базой данных ORM слой
require 'erb'				# Наш шаблонизатор

class Transact < ActiveRecord::Base		# Одна табличка, звать transacts
end

ActiveRecord::Base.establish_connection
	:adapter => "sqlite3", 				# Нет комментариев
	:database => "dbfile"				# имя файла - классическое
	
get "/" do
  "Hello world"
end

Вот и все, дальше **:wq** – для тех, кто не знает как выходить из vim-a. Отныне по комманде


$ ruby empty.rb

У нас на 4567 порту запускается свой вебсервер, который запускает указанное приложение, которое при входе на главную страницу выдает пустой файл с текстом “Hello world”

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


get "/" do
  @transact = Transact.find(:all)
  page = ""
  @transact.each do |one|
      page += "<p>"+one.id.to_s+". "+"<strong> #{one.name.to_s} </strong>"+"</p>"
  end
  page
end

Если все правильно, то мы должны были получить целый список книг.

Но нам же надо не так, нам надо с шаблонами, базой данных, блекджеком и шлю…преферансом и поэтессами.
Поэтому создадим для начала наши шаблоны в папке views. Назовем их говоряще: index.erb и result.erb

Теперь доработаем наш основной код, чтобы он работал с шаблоном:


get "/" do
  @transact = Transact.find(:all)
  erb :index
end

Общая идея остается та же, поэтому шаблон очень похож на вырванный кусок кода:


<% @transact.each do |one| %>
    <li>
      <p><%= one.id %> <input type="checkbox" name="<%= one.id %>" /> <strong><%= one.name %></strong></p>
      <p><%= one.body %></p>
    </li>
<% end %>

Украшательства добавить по вкусу, завернуть весь шаблон в <form action=”/result” method=”post”> и добавить снизу
<input type=”submit” /> для удобства.

Принимать результаты запроса тоже просто:


post "/result" do
   @params = params             # наши параметры
   @transact = Array.new        # пустой массив для результатов
   @params.each do |one|        # берем параметры по одному
     @transact << Transact.find_by_id(one) # и добавляем в массив результатов
   end
   erb :result
end

В обработчике результатов тот же шаблон, что и на главной:

Список прочитанных мною книг из сотни романов, которые,
по мнению коллектива редакции «НГ-Ex libris», потрясли
литературный мир и оказали влияние на всю культуру.

<%= @transact.size %> из 100

<%= "

    " unless @transact.empty? %>
    <% @transact.each do |one| %>

  • <%= one.id %>. <%= one.name %>
  • <% end %><%= "

" unless @transact.empty? %>

Вот такая загогулина получается.

В следущих сериях своего ламоблогбастера, я расскажу, как запустить все это под apache2 + mod_rails, про лучи позора и ненависти в сторону платежной системы Nochex и как отсылать из sinatra письма, если опять не разхондрюсь и не забью на блог на 144 дня.