Гостевая
Форум
Разделы
Главная страница
Js скрипты
Php скрипты
Html шаблоны
Книги по Web дизайну
Статьи


Главная страница статей --> Хитрости при программировании php, заметки по базам данных

Что такое Ruby on Rails 1.0?

Источник: realcoding.net

Прошло около года с момента публичного дебюта Ruby on Rails в 25 июля, 2004. За этот довольно короткий срок, Rails превратилась из уже достаточно впечатляющей версии 0.5 в устрашающе-вдохновляющую, готовящуюся к выходу версию 1.0, которой удалось сохранить свою простоту использования и продуктивность, в то же время добавив будоражащий ум массив новых возможностей. Эта статья познакомит вас с компонентами грядущей версии Ruby on Rails 1.0 и постарается рассказать, о чём же собственно столько разговоров.

Я не намереваюсь учить вас как использовать Rails для создания веб приложений. Для этого, вам скорей всего следует начать со статьи Rolling with Ruby on Rails. Эта статья, является введением и картой к огромному количеству возможностей Rails.

Высокая продуктивность и высокая скорость разработки


На уровне возможностей, Ruby on Rails не предлагает ничего нового. Существующие веб фреймворки уже всё это делали. В чём же тогда дело? Различие лежит в том, как это делает Ruby on Rails. Когда вы можете закончить простое веб приложение за дни вместо недель и более сложное за недели вместо месяцев, люди обращают на это внимание!

Это внимание было бы недолгим, если бы получавшиеся приложения были запутаны и их было бы тяжело поддерживать или расширять. К счастью, Ruby on Rails действительно облегчает правильные методы программирования, что приводит к хорошо сформированному и легко поддерживаемому коду.

Внимание также оказалось бы недолгим, если бы Ruby on Rails не имела глубины — то есть, если бы раз попробовав использовать её для чего-то сложнее самого простого веб приложения, вы сразу натыкались бы на стену, не имея возможности продолжить из-за ограничений системы. Опытные разработчики, которые знают толк во всемирной паутине и программировании не перестают повторять, что для Rails это не так. К примеру, автор Tomcat, Ant и Servlet API, James Duncan Davidson недавно написал:

Rails это самая хорошо продуманная среда веб разработки которую я когда-либо использовал. И это за десять лет моей работы веб разработчиком. Я разрабатывал свои фреймворки, помогал разрабатывать Servlet API, и создал больше пары веб серверов с нуля. До Rails, никто раньше так не делал. Я не хочу сказать что они всё сделали правильно. Ни под каким видом она не совершенна. У меня есть несколько придирок к тому как всё собрано вместе. Но дело не в совершенстве. Дело в том, что Rails позволяет работать очень быстро, при том что есть глубина которая помогает вам двигаться вперёд. И у Rails это очень хорошо получается.


Может быть сложно поверить в то, что это возможно без какого-то значительного недостатка. К счастью, вам не придётся верить мне на слово (также как кому-либо ещё). Вы можете легко доказать себе за день или меньше просто пройдя через учебник по Ruby on Rails и тут же разработав скромное приложение на свой выбор. В конце концов, лучше один раз увидеть, чем сто раз услышать. Если вы не хотите смотреть на себя сверх продуктивного, вы всегда можете посмотреть на кого-то ещё, кто за вас делает всё это в новом Rails видео.

Как Rails это делает?


Как хороший рецепт, Rails помогает вам достичь этого нового уровня продуктивности сочетая правильные ингриденты в правильном количестве. Вот несколько из важных ингридиентов который делают Rails такой, какая она есть.

Большая часть мощи Rails кроется в языке программирования Ruby. Уникальный дизайн Ruby делает легким создание языков для разных предметных областей и метапрограммирование. Rails пользуется этим на полную катушку.

Полная реализация MVC


Rails это MVC (модель, вид, представление) фреймворк, она предоставляет компоненты для каждого уровня которые безупречно работают друг с другом. Другие фреймворки часто реализуют только часть решения, обязывая разработчика интегрировать несколько различных фреймворк в приложение, а затем заставить их работать вместе. (К примеру, Java разработчик может использовать Hibernate, Struts и Tiles для полной поддержки MVC.)

Соглашение вместо конфигурации


Соглашение вместо конфигурации означает конец подробным файлам конфигурации на XML — в Rails нет ни одного! Вместо трудоёмкого XML, приложение на Rails использует несколько простых программерских соглашений которые позволяют узнать всё через рефлекцию и обнаружение. Например, Rails использует разумную рефлекцию для привязки таблиц базы данных к объектам Ruby. Код вашего приложения и работающая база данных уже содержат всё, что Rails нужно было знать.

Меньше кода


Следование простым программным соглашениям Rails не только устраняет необходимость в конфигурационных файлах. Оно также означает что Rails может автоматически брать на себя мириады низко-уровневых деталей, без необходимости вам говорить ей об этом. Это значит, что вам приходится писать меньше строк кода чтобы реализовать своё приложение. А чем меньше кода, тем быстрее идёт разработка и тем меньше багов, что делает код легким для понимания, поддержки и расширения.

Генераторы


То как Rails использует динамическую рефлекцию и метапрограммирование устраняет большую часть типового кода который вам в противном случае пришлось бы писать. Но часто, можно избежать написания и оставшейся его части используя встроенные скрипты-генераторы. Это даёт вам больше времени чтобы сконцентрироваться на коде который действительно важен — вашей бизнес-логике.

Быстрая отдача


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

Скаффолдинг (Scaffolding — строительные леса, подмости. Прим. пер.)


Rails может автоматически создать полный набор CRUD (Create, Retrieve, Update, and Delete) операций и представления для любой таблицы базы данных. Эта функциональность называется скаффолдингом и помогает вам быстрее начать манипулировать своими таблицами. Со временем, вы можете постепенно заменить сгенерированные операции и представление своими собственными — которые, разумеется, будут намного красивее и функциональнее.

Компоненты Rails


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


* Active Record это слой объектно-реляционного отображения (ORM) который связывает бизнес объекты (модели) с таблицами базы данных. Это реализация паттерна активная запись описанного Мартином Фаулером.
* Action Pack это компонент который реализует два слоя архитектуры MVC: контроллер и представление. Контроллер управляет входящими запросами от браузера пользователя и отправляет их к соответствующему методу класса-контроллера. Представление строит ответ браузеру используя шаблонную систему на подобии ASP или JSP.
* Prototype это компонент который реализует Ajax, dragndrop и визуальные эффекты на ваших страницах.
* Action Mailer это тот компонент который отвечает за отправку и получение электронной почты.
* Action Web Service позволит вам легко добавить API веб службы к своему приложению. Action Web Service поддерживает SOAP, XML-RPC и WSDL.

* Active Record is the object-relational mapping (ORM) layer that connects business objects (models) to database tables. It is an implementation of the Active Record pattern described by Martin Fowler.
* Action Pack is the component that implements both the view and controller portions of the MVC architecture. The controller part handles incoming requests from the users browser and routes them to the correct method of a controller class. The view part builds the response to send back to the browser using a templating system similar to that of ASP or JSP.
* Prototype is the component that implements the Ajax, drag-and-drop, and visual effects within your web pages.
* Action Mailer is the component that handles the sending and receiving of email.
* Action Web Service is the component that makes it easy to add web service APIs to your web application. Action Web Service supports SOAP, XML-RPC, and WSDL.

Основные возможности


У Rails есть некоторые основные и специфичные характеристики.

Веб серверы


Rails можно запустить практически на любом веб сервере который поддерживает CGI. Однако, производительность CGI никуда не годится, поэтому предпочитаемый способ развёртывания это использование FastCGI. Довольно хорошо протестирован способ развёртывания Rails приложений на Apache и LightTPD. Кстати, недавно появился новичок, SCGI, который предоставляет производительность FastCGI без сложностей его установки.

Во время разработки, чаще всего самым простым способом является использование WEBrick — веб сервера который поставляется вместе с Ruby.

Базы данных


На данный момент Rails поддерживает следующие СУБД:

* MySQL
* PostgreSQL
* SQLite
* SQL Server
* DB2
* Oracle

Сам адаптер базы данных состоит из примерно 100 строк Ruby кода, поэтому расширить этот лист ещё одним элементом не составит большого труда.

Отладка


Когда что-нибудь в вашем Rails приложении идёт не так как надо, обычно вы получите довольно детальное сообщение об ошибки в вашем браузере (если вы работаете в режиме разработки). Часто, этого достаточно чтобы обнаружить проблему. Если нет, то у вас есть следующие варианты отладки:

* Вставить отладочный вывод в контроллер. Например:

render_text Дошёл до сюда

or

render_text объект user = + user_obj

* Проверить логи Rails. (Используйте tail на *nix системах.) Посмотрите на файлы development.log, production.log и fastcgi.crash.log. Помните, что ваш веб сервер тоже ведёт логи.
* Использовать брейкпоинты.
* Использовать коммерческую среду разработки (такую как ArachnoRuby) со встроенным отладчиком.

Настраиваемые (красивые) URL


То, как Rails по умолчанию привязывает URL к действиям контроллера очень просто понять. Rails очень старается чтобы пользователь видел только красивые URL адреса. URL в Rails простые и понятные, а не длинные и зашифрованные.

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

Система роутинга Rails это чистый Ruby код который позволяет вам использовать даже регулярные выражения. Поскольку Rails не использует возможности веб сервера при привязке URL (например mod_rewrite в Apache), ваша схема привязки URL будет работать одинаково на любом веб сервере.

Модульное тестирование


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

* Генерация новых контроллеров, моделей и скаффолдига, также создаёт соответствующие скелеты модульных тестов.
* Чёткое следование архитектуре MVC как результат приводит к хорошо тестируемым действиям и компонентам.
* Rails включает в себя Rake (Ruby Make) скрипт, который может автоматически запускать все ваши модульные тесты.

Детали процесса подробно описаны в Руководстве о тестировании в Rails.

Active Record


Active Record это часть Rails которая отвечает за автоматическую динамическую привязку таблиц вашей базы данных к объектам моделей. Это буква M в MVC, и это реализация слоя ORM в Rails.

Для самых распространённых случаев использования (и не таких уж распространённых), вам никогда не придётся видеть или писать SQL код для доступа к или обновления вашей базы. Цель Active Record — работать исключительно с реляционными базами данных; она не пытается абстрагироваться от использования SQL. Когда надо, Active Record облегчает использование ваших собственных SQL запросов, для тех сложных случаев где это необходимо. Но даже в таких случаях, часто можно обойтись без написания SQL кода вручную.

Автоматическая привязка


Active Record автоматически привязывает таблицы к классам, строки к объектам (экземплярам класса модели), и поля к аттрибутам объекта. Например код:

class Product < ActiveRecord::Base
end

автоматически привязывается к таблице с именем products, такой как:

CREATE TABLE products (
 
id int(11) NOT NULL auto_increment,
 
name varchar(255),
 
PRIMARY KEY (id)
);

а также автоматически создаёт аттрибут name который вы можете использовать так:

my_product = Product.find(:first)
STDOUT.print my_product.name
my_product
.name = Название нового продукта

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

* Класс модели Invoice привязывается к таблице invoices.
* Класс модели Person привязывается к таблице people.
* Класс модели Country привязывается к таблице countries.
* Класс модели SecurityLevel привязывается к таблице security_levels.

Соглашение о единственных/множественных числах выливается в довольно натурально читаемый код. Заметьте как разумна привязка в своём использовании правил плюрализации английского. Также обратите внимание, что имена классов используют CamelCase (правило Ruby), в отличии от таблиц, имена которых все в нижнем регистре со знаками нижнего подчёркивания между словами.

В тех случаях когда это не срабатывает (например тогда, когда вам приходится работать с устаревшей базой данных, где вы не имеете контроля над именами таблиц), вы можете прямо указать Active Record какое имя следует использовать.

Документация класса ActiveRecord::Base описывает процесс автоматической привязки подробней.

<h3>Ассоциации</h3>

Таблицы не существуют в одиночестве. По крайней мере, обычно. Большинство приложений для баз данных используют несколько таблиц со своими отношениями между ними. Вы можете рассказать Active Record об этих отношениях в классах своих моделей, и Active Record сгенерирует целый набор методов для навигации по ассоциациям, которые помогут вам получить доступ к нужным данным. Следующий код модели:

class Firm < ActiveRecord::Base
  has_many   
:clients
  has_one   
:account
  belongs_to
:conglomerate
end

позволяет вам написать следующий код:

my_firm = Firm.find(:last)
STDOUT.print my_firm.account.name
STDOUT
.print my_firm.conglomerate.employee_count
for c in my_firm.clients
  STDOUT
.print Клиент: + c.name + n
end

Этот код будет работать корректно если в базе данных есть таблицы clients и accounts в каждой из которых есть поле name, и таблица conglomerates с полем employee_count.

Документация модуля ActiveRecord::Associations подробно объясняет все тонкости ассоциаций в Rails.

Валидация


Поскольку вы скорей всего не хотите хранить в своей базе что попало, вы скорей всего захотите проверить свои данные перед сохранением. Active Record содержит набор макро-подобных валидаторов которые вы можете добавить к своей модели.

class Account < ActiveRecord::Base
  validates_presence_of    
:subdomain, :name, :email_address, :password
  validates_uniqueness_of   
:subdomain
  validates_acceptance_of   
:terms_of_service, :on => :create
  validates_confirmation_of
:password, :email_address, :on => :create
end

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

class Person < ActiveRecord::Base
  protected
    def validate
      errors
.add_on_empty %w( first_name last_name )
      
errors.add(phone_number, has invalid format) unless phone_number =~ /[0-9]*/
   
end

    def validate_on_create
# only runs the first time a new object is saved
      
unless valid_discount?(membership_discount)
       
errors.add(membership_discount, has expired)
      
end
    end

    def validate_on_update
      errors
.add_to_base(Изменений не было) if unchanged_attributes?
   
end
end

person
= Person.new(first_name => David, phone_number => what?)
person.save                         # => false (and doesnt do the save)
person.errors.empty?                # => false
person.count                        # => 2
person.errors.on last_name        # => cant be empty
person.errors.on phone_number     # => has invalid format
person.each_full { msg puts msg } # => Last name cant be emptyn +
                                           
Phone number has invalid format
person.attributes = { last_name => Heinemeier, phone_number => 555-555 }
person.save # => true (и person сохраняется в базе данных)

Если метод validate существует, Rails вызовет его прямо перед записью любого объекта в базу данных. Если валидация провалилась, она не запишет объект в базу. Методы validate_on_create и validate_on_update похожи, за исключением того, что первый вызывается только тогда когда Rails создаёт в базе новую запись, тогда как последний вызывается только когда Rails собирается обновить существующую.

Документация модуля ActiveRecord::Validations подробно описывает все тонкости.

Обратные вызовы

Вы можете наблюдать за тем, как Active Record создаёт и удаляет объекты модели, создаёт и изменяет их в базе данных, используя методы обратных вызовов (callbacks). Вы можете использовать обратные вызовы для того, чтобы позаботиться о сложной бизнес логике, изменить данные перед тем как Rails запишет их в базу (или после того как Rails прочитает их из базы), или в любой другой момент который вам нужен.

К примеру, метод save который сохраняет данные объекта модели в базу данных, имеет восемь методов обратного вызова:

1. before_validation
2. before_validation_on_create
3. after_validation
4. after_validation_on_create
5. before_save
6. before_create
7. after_create
8. after_save

Это даёт вам полный контроль над объектами модели тогда, когда он вам нужен.

class CreditCard < ActiveRecord::Base
 
# Выдрать всё, кроме цифр, так чтобы пользователь мог ввести 555 234 34 или
  # 5552-3434. Чтобы оба варианта значили 55523434
 
def before_validation_on_create
    self
.number = number.gsub(/[^0-9]/, ) if attribute_present?(number)
 
end
end

class Subscription < ActiveRecord::Base
  before_create
:record_signup

  private
    def record_signup
      self
.signed_up_on = Date.today
    end
end

class Firm < ActiveRecord::Base
 
# Уничтожает ассоциированных клиентов и людей, когда уничтожается фирма
 
before_destroy { record Person.destroy_all firm_id = #{record.id} }
 
before_destroy { record Client.destroy_all client_of = #{record.id} }
end

Документация модуля ActiveRecord::Callbacks подробно рассказывает о методах обратного вызова.

Транзакции

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

transaction do
 
david.withdrawal(100)
 
mary.deposit(100)
end

Транзакции уровня базы данных, показанные выше, не допустят снятие денег со счёта Davidа в случае если не получится зачислить эти деньги на счёт Mary. Однако, это не защитит объекты david и mary от изменения. Чтобы добиться этого, вам следует использовать транзакции уровня объектов:

Account.transaction(david, mary) do
 
david.withdrawal(100)
 
mary.deposit(100)
end

Любой сбой в этом коде вернёт назад предыдущее состояние объектов, также как и базы данных.

Документация модуля ActiveRecords::Transactions объясняет подробнее.

И это далеко не всё

Active Record содержит в себе намного больше, чем я могу здесь описать. Чтобы узнать больше, загляните в Active Record API.

Action Pack

Action Pack реализует уровни контроллера и представления в Rails.

Шаблоны представления

Шаблоны представления формируют HTML который возвращается в ответе браузеру. Шаблоны являются файлами rhtml (HTML со встроенным Ruby) которые очень похожи на ASP или JSP файлы. Текст внутри <% %> это Ruby код который будет запущен, а текст внутри <%= %> это Ruby код который будет также запущен и результат запуска которого будет подставлен обратно в HTML.

<html>
  <
head>
    <
title>Счета для <%= @name %></title>
  </
head>
  <
body>
    <%
render_partial invoices_by_customer %>
  </
body>
</
html>

По умолчанию, Rails попытается найти шаблон чьё имя совпадает с действием которое сейчас выполняется. Если например, Rails выполняет действие edit в вашем InvoiceController, тогда она попытается найти и вывести шаблон представления .../app/views/invoices/edit.rhtml.

Вы можете также конструировать XML (или HTML) вывод в действии вашего контроллера. Это полезно, к примеру, для построения RSS лент или ответа на XML-RPC запросы. В следующем примере, xm это экземпляр класса XmlMarkup.

xm.em(подчёркнутый)    # => <em>подчёркнутый</em>
xm.em { xmm.b(emp & bold) }    # => <em><b>emph & bold</b></em>
xm.a(A Link, href=>http://onestepback.org)    # => <a href=http://onestepback.org>A Link</a>
xm.div { br }    # => <div><br/></div>
xm.target(name=>compile, option=>fast)
   
# => <target option=fast name=compile>
    # ВНИМАНИЕ: порядок аттрибутов не сохраняется.

xm.instruct!    # <?xml version=1.0 encoding=UTF-8?>
xm.html {    # <html>
  xm.head {    #   <head>
   xm.title(История)    #     <title>История</title>
}    #   </head>
  xm.body {    #   <body>
    xm.comment!  HI    #     <!-- HI -->
   xm.h1(Заголовок)    #     <h1>Заголовок</h1>
   xm.p(параграф)    #     <p>параграф</p>
}    #   </body>
}    # </html>

Роутинг URL


Запрашиваемый URL всегда привязывается к какому-то действию внутри контроллера. Контроллер это простой класс Ruby и каждое действие реализованное контроллером это публичный метод этого класса. По умолчанию, URL привязан к действию по следующей схеме:

/:controller/:action/:id

Это легче всего объяснить на примере. Если Rails получает URL http://myapp.com/invoices/show/37, то она автоматически привяжет его к классу-контроллеру InvoicesController и к методу этого класса под именем show. Rails также передаст значение 37 в метод как часть хэша параметров под именем id. Хэш параметров содержит в себе значения полей запроса(взятых из URL) и данные элементов форм. Код может выглядеть следующим образом:

class InvoicesController
  def show
   
@invoice = Invoice.find(params[:id])
 
end
end

Поскольку действия это методы сгруппированные внутри контроллера (вместо отдельных командных объектов), они могут легко разделять между собой вспомогательные методы.

Если стандартный способ привязки URL вас не устраивает, вы можете с лёгкостью указать свои правила роутинга, даже используя регулярные выражения. Поскольку Rails реализует свой механизм URL роутинга, вам не надо связываться с Apache mod_rewrite и ваши правила роутинга будут работать одинаково на всех веб серверах.

Правила роутинга URL в Rails это простой Ruby код. Вот пример:

map.connect date/:year/:month/:day,
     :
controller => blog,
     :
action => by_date,
     :
month => nil,
     :
day => nil,
     :
requirements => {:year => /d{4}/,
                       :
day => /d{1,2}/,
                       :
month => /d{1,2}/}

С этим правилом роутинга становятся рабочими следующие адреса:

http://myblog.com/date/2005
http://myblog.com/date/2005/08
http://myblog.com/date/2005/08/01

Это правило разбивает URL содержащий дату, которую, блог может использовать для отображения постов за конкретное число. URL который совпадает с правилом будет привязан к классу BlogController и к методу by_date. Хэш параметров будет содержать значения для года из четырёх цифр(/d{4}/ это регулярное выражение Ruby) и месяц и день из двух. Также, месяц и день не обязательны; если значение не присутствует, в хэше параметров будет сохранено значение по умолчанию — nil.

Смотрите руководство по роутингу в Rails для подробного описания.

Фильтры

Фильтры позволяют вам выполнять предварительный код перед тем как Rails выполнит действие, а также после его выполнения. Это может быть полезно для таких вещей как кэширование или аутентификация перед вызовом действия, и компрессия или локализация ответа после его вызова. Фильтр before_filter может либо разрешить действию быть выполненным в нормальном режиме, возвратив true, либо отменить вызов вернув false (или выполнив операцию render или redirect).

Например:

class BankController < ActionController::Base
  before_filter
:audit

  private
    def audit
      
# записать действие и параметры в лог для аудита
   
end
end

class VaultController < BankController
  before_filter
:verify_credentials

  private
    def verify_credentials
      
# убедиться что пользователь имеет доступ в хранилище
   
end
end

Остальные детали в документации класса ActionController::Filters.

Помошники (helpers)

Помошники это умные методы (функции) которые помогают вашим шаблонам представления генерировать HTML. Они используют ваши объекты модели и классы контроллеров для создания HTML и в дальнейшем, избавят вас от траты лишнего времени и усилий. Конечно, это также значит что вам придётся писать меньше строк кода, но держу пари, об этом вы уже итак догадались.

Вы можете создавать своих собственных помошников, но как вы могли догадаться несколько помошников поставляется встроенными в Rails. Помошник link_to, например, генерирует тэги ссылок которые ссылаются на контроллеры и действия. Пример:

<%= link_to Помощь, { :action => help } %>

создаёт ссылку на действие help (метод) в текущем контроллере (том, который обрабатывает текущий запрос). Текст ссылки (видимый пользователем) будет "Помощь."

<%= link_to Содержание справки,
           { :
controller => help, :action => index }
%>

Это создаёт ссылку на метод index контроллера HelpController. Текстом ссылки будет "Содержание справки."

<%= link_to Удалить этот счёт,
           { :
controller => invoices,
             :
action => delete,
             :
id => @invoice.id },
             :
confirm => Вы действительно хотите это удалить?
%>

Это создаст ссылку на метод delete в классе InvoiceController, и передаст параметр id (в качестве указателя на то, какой счёт нужно удалить). Здесь также используется специальная опция confirm которая создаёт всплывающее окно подтверждения через JavaScript.

Существует большой набор помощников для создания форм просмотра и обновления значение объектов ваших ActiveRecord моделей, то есть -- для значений в вашей базе данных. Предположим что в вашей базе данных есть таблица people со столбцами для имени, пароля, описания и булева значения определяющего женат человек или холост (ОК, довольно странная табличка вышла :). Вот часть шаблона с примером тэгов формы которые можно было бы использовать. (Допустим что переменная @person содержит объект класса Person, считанный из строки в таблице people.)

<form action=save_person method=post>
 
Имя:
  <%=
text_field person, name, size => 20 %>

 
Пароль:
  <%=
password_field person, password, maxsize => 20 %>

 
Холост?:
  <%=
check_box person, single %>

 
Описание:
  <%=
text_area person, description, cols => 20 %>

  <
input type=submit value=Сохранить>
</
form>

Данный код генерирует следующий HTML ответ:

<form action=save_person method=post>
 
Имя:
  <
input type=text id=person_name name=person[name] size=20 value=<%= @person.name %> />

 
Пароль:
  <
input type=password id=person_password name=person[password]
         
size=20 maxsize=20 value=<%= @person.password %> />

 
Холост?:
  <
input type=checkbox id=person_single name=person[single] value=1 />

  Описание:
  <textarea cols=
20 rows=40 id=person_description
           name=
person[description]>
    <%= @person.description %>
  </textarea>

  <input type=
submit value=Сохранить>
</form>

Есть помощники для создания тэгов option для списков select из набора строк считанных из базы данных; помощники для работы с датами, числами и валютой; и много других.

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

* Active Record Helpers
* Asset Tag Helpers
* Benchmark Helpers
* Cache Helpers
* Capture Helpers
* Date Helpers
* Debug Helpers
* Form Helpers
* Form Options Helpers
* Form Tag Helpers
* JavaScript Helpers
* Number Helpers
* Pagination Helpers
* Tag Helpers
* Text Helpers
* Upload Progress Helpers
* URL Helpers

AJAX и JavaScript помощники

Rails включает в себя JavaScript библиотеку Prototype для реализации своей поддержки AJAX, визуальных эффектов и drag-n-drop возможностей.

Модель того, как Rails реализует AJAX операции проста и надёжна. Как только браузер обработал и отобразил первоначальную страницу, различные действия пользователя могут вызвать либо отображение новой страницы (как в традиционных веб-приложениях) либо инициировать AJAX действие:

1. Срабатывает триггер. Это может быть кликом пользователя на кнопку или ссылку, изменение данных в форме или поле, или просто временный триггер (на основе таймера).
2. Клиент асинхронно отсылает данные ассоциированные с триггером (поле или целую форму) к действию-обработчику на стороне сервера через XMLHttpRequest.
3. На стороне сервера действие-обработчик выполняет какие-то действия над данными и возвращает HTML фрагмент в качестве ответа.
4. JavaScript на стороне клиента (код генерируется Rails автоматически) принимает этот HTML фрагмент и использует его для обновления конкретной части HTML текущей страницы, часто фрагмент подставляется содержимым в тэг <div>.

Вся прелесть в том, как просто Rails позволяет реализовать всё это в вашем веб-приложении. Следующий простой пример добавляет новые элементы в список:

<html>
  <
head>
    <
title>Демонстрация списка с AJAX</title>
    <%=
javascript_include_tag prototype %>
  </
head>
  <
body>
    <
h3>Добавить к списку с помощью AJAX</h3>
    <%=
form_remote_tag(:update => my_list,
                           :
url => { :action => :add_item },
                           :
position => top ) %>
      
Текст нового элемента:
      <%=
text_field_tag :newitem %>
      <%=
submit_tag Добавить элемент через AJAX %>
    <%=
end_form_tag %>
    <
ul id=my_list>
      <
li>Начальный элемент... добавьте ещё!</li>
    </
ul>
  </
body>
</
html>

Статья AJAX on Rails и API JavaScript помощников рассказывают о поддержке AJAX в Rails более подробно.

Библиотека Prototype также предоставляет Rails разработчику целый набор визуальных эффектов на стороне браузера. Script.aculo.us содержит документацию и живую демонстрацию эффектов Prototype. Prototype также позволяет легко добавить к своему приложению drag-and-drop функциональность, об этом также можно узнать на сайте script.aculo.us.

Макеты (Layouts)

Макеты позволюят вам указать набор основных элементов для отображения на каждой странице выдаваемой контроллером. Это обычно полезно для вывода общей шапки, низа и боковых панелей. По умолчанию, Rails смотрит в свой каталог layouts в поисках rhtml файла чьё имя совпадает с именем контроллера. Шаблон макета может выглядеть вот так:

<html>
  <
head>
    <
title><%= @page_title %></title>
  </
head>
  <
body>
    <
div>Шапка для этого макета</div>
    <
div><%= @content_for_layout %></div>
    <
div>Низ этого макета</div>
  </
body>
</
html>

Rails подставит HTML который сгенерируется действием в этот макет, в то место где написано @content_for_layout.

Контроллер также может прямо указывать какой макет следует использовать для всех его действий. Это упрощяет задачу использования одного макета для нескольких контроллеров. Вы можете менять шаблон макета даже динамически, в режиме runtime. Например, использовать разные макеты для пользователей вошедших в систему и для анонимных посетителей.

Чтобы узнать о макетах больше, смотрите документацию ActionController::Layout.

Partials и компоненты

Компоненты и partials (части, отрывки. прим.пер.) позволяют вам разделить ваши шаблоны представления на модули.

Проще всего использовать partials, которые позволяют вам выделить общую часть шаблона в отдельный файл и затем отображать его из множества других шаблонов (или много раз в одном шаблоне).
Шаблоны partials всегда имеют знак нижнего подчёркивания (_) перед названием их файла, чтобы было легче отлечить их от полных шаблонов.

Типичный пример использования partials это отображение массива (или другой коллекции) элементов.

<% for ad in @advertisements %>
  <%=
render :partial => adview, :locals => { :item => ad } %>
<%
end %>

Это отобразит шаблон partial _adview.rhtml несколько раз (по разу на каждый элемент массива @advertisments). Для каждого отображения, Rails будет передавать в _adview.rhtml локальную переменную с именем item которая содержит объект ad.

Документация ActionView::Partials содержит подробную информацию. На Pointstorm есть более детальная презентация partials, но она несколько устарела, поскольку использует устаревший синтаксис вызова partials.

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

<%= render_component :controller => calendar, :action => today %>

Загляните в раздел Компоненты руководства по Rails если хотите узнать больше.
Скаффолдинг (scaffolding)

Скаффолдинг позволяет вам получить быструю реализацию CRUD (Create, Retrieve, Update, and Delete) операций для любой таблицы базы данных. Они не очень красивы, но позволяют получить немедленный доступ через веб-интерфейс к вашим таблицам. С течением времени, вы можете постепенно заменить сгенерированные операции и шаблоны на свои.

Rails поддерживает статический и динамический скаффолдинг. Статический физически генерирует модель, контроллер и файлы шаблонов. Это позволяет вам увидеть как всё работает и начать улучшать и изменять существующий код. Для генерации статического скаффолдинга, зайдите через файловую систему в главный каталог вашего Rails приложения и выполните команду на подобии этой:

$ ruby script/generate scaffold invoices

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

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

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

class AccountController < ActionController::Base
  scaffold
:account
end

И много всего другого

Также как и в Active Record, в Action Pack очень много вещей о которых я не могу здесь рассказать. Если хотите узнать больше, посмотрите на Action Pack API.

Action Mailer

Action Mailer это простая технология для отправки и приёма email в вашем веб-приложении. Вот метод для отправки email с вложением:

# отправляем email с вложением
def signup_notification(recipient)
 
recipients recipient.email_address_with_name
  subject
Информация о новом аккаунте
 
from system@example.com

 
attachment :content_type => image/jpeg, :body => File.read(an-image.jpg)

 
attachment application/pdf do a
   
a.body = generate_your_pdf_here()
 
end
end

Узнать больше можно в Action Mailer API и главе 19 книги Agile Web Development with Rails.

Action Web Service

Action Web Service реализует серверную поддержку для протоколов веб-служб SOAP и XML-RPC, позволяет просто создавать свои API и публиковать их через WSDL.

Вот часть MetaWeblog API реализованного Typo (open source блог система написанная на Rails):

class MetaWeblogApi < ActionWebService::API::Base

  api_method
:getRecentPosts,
    :
expects => [ {:blogid => :string},
                  {:
username => :string},
                  {:
password => :string},
                  {:
numberOfPosts => :int} ],
    :
returns => [[MetaWeblogStructs::Article]]

 
api_method :deletePost,
    :
expects => [ {:appkey => :string},
                  {:
postid => :string},
                  {:
username => :string},
                  {:
password => :string},
                  {:
publish => :int} ],
    :
returns => [:bool]
end

class MetaWeblogService < TypoWebService
  web_service_api MetaWeblogApi

  def getRecentPosts
(blogid, username, password, numberOfPosts)
   
articles = Article.find_all(nil, created_at DESC, numberOfPosts)
   
articles.to_a.collect{ c article_dto_from(c) }
 
end

  def deletePost
(appkey, postid, username, password, publish)
   
article = Article.find(postid)
   
article.destroy
    true
  end
end

Этот отрывок показывает только два из семи методов API определённых Typo в этом классе.

Если хотите узнать больше, прочтите руководство по Action Web Service

Мысли о разделении

Обычно можно разделить фреймворки для создания веб-приложения и разработчиков которые их используют на две отдельных категории. В одном конце спектра находятся фреймворки-тяжеловесы для "серъёзных" программистов, на другой -- лёгкие, простые для использования фреймфорки для любителей "поиграть." Каждая из этих групп чаще всего относится друг к другу без всякого уважения.

Одна из самых интересных вещей в том, что Rails привлекает разработчиков из обоих лагерей. Высококлассные разработчики устали от повторяющейся, низкопродуктивной рутины которую они должны терпеть, в то время как разработчики помельче устали сражаться с кашей из неподдерживаемого кода когда их приложение переходит выходит из разряда простых. Обе эти группы считают, что Rails снимает значительное количество их проблем. Я не знаю как вам, но мне это кажется замечательным фактом.

На данный момент, Ruby on Rails занимает всего-лишь маленький процент среди проектов веб-разработки. Однако она быстро нагнетает интерес вокруг себя, и многие уважаемые лидеры среди разработчиков ПО уже пробуют использовать Rails и публично восхваляют её.

Возможно настало время вам тоже попробовать Rails, чтобы самому убедиться о чём же собственно весь шум.



Похожие статьи:
- Фильтры DHTML
- Поиск по сайту - статичный контент (Perl)
- Как подружить интерпретатор Perl с Homesite
- Работа с MS Access в PHP
- История языка HTML
- CSS + RSS = почти идеальный блог?
- Денвер + Ruby On Rails, мануал по установке
- Варианты настройки Ruby On Rails на максимальную производительность: mongrel vs lighttpd vs nginx
- Преимущества индексации страниц с mod_rewrite
- Как узнать сколько раз скачали ваш файл
- Как сгенерировать файл .htaccess
- Проект “Ы”, Ruby on Rails, Acts as Taggable, скорость разработки
- Что нового будет в Rails 1.1 и немного секретов Prototype.js


Оглавление | Обсудить на форуме | Главная страница сайта | Карта сайта |
[0.001]