Даведнік па Rails

Rails debug in NetBeans

Essential Ruby & Rails 3 Reading

Testing with Rspec

Rails HTTP status code to symbol mapping

Rails forms processing

respond_with in Rails3

inherited_resources plugin/gem

Parsing dates and times in Ruby and Rails with Chronic gem

Spree – E-Commerce Platform on RoR

24 Extremely Useful Ruby Gems for Web Development

Getting Compass to Work With Rails 3.1 (and 3.2)

ActiveInteraction – gem for managing application specific business logic

Ahoy – Simple, powerful visit tracking for Rails

Test Driven Rails, Part 1 and Part 2

Creating and Customizing Rails Generators & Templates і Rails Application Templates

Top 8 tools for Ruby on Rails code optimization and cleanup

Enums and Queries in Rails 4.1, and Understanding Ruby

Phone verification using SMS via Twilio

Regularity - Regular expressions for humans

Карысныя спасылкі

http://rubyonrails.org

Ruby + Rails (вельмі добра рэалізаваны пошук): http://railsapi.com/doc/rails-v3.0.8rc1_ruby-v1.9.2/

http://api.rubyonrails.org

http://www.rubydoc.info/docs/rails/3.0.0/frames

http://apidock.com/rails

Інтэрактыўная шпаргалка на OverAPI: http://overapi.com/rubyrails/

Галоўная старонка афіцыйных даведнікаў

RailsApps project

Вельмі добры вучэбнік

http://www.bigfatrails.com/book/

http://railscasts.com

Апошнія Ruby і Rails навіны на envylabs.com: http://ruby5.envylabs.com/

http://railsapps.github.com/installing-rails.html

http://edgeguides.rubyonrails.org/upgrading_ruby_on_rails.html

Пачынаем

Што такое Rails?

Rails – гэта фрэймворк распрацоўкі сеціўных праграмаў, напісаны на мове праграмаваньня Ruby. Ён спраектаваны такім чынам, каб зрабіць працэс стварэньня сеціўных праграмаў прасьцейшым, улічваючы тыя аспэкты, зь якімі вымушаны сутыкацца бальшыня распрацоўшчыкаў. Rails дазваляе пісаць менш коду, рашаючы пры тым больш задачаў, чым іншыя мовы ці фрэймворкі.

Дадзены фрэймворк грунтуецца на дапушчэньні, што ў шэрагу магчымых рашэньняў заўсёды існуюць найлепшыя, і ён «заахвочвае» распрацоўшчыка да карыстаньня імі, і часам нават робіць «перашкоды» на шляху карыстаньня ня лепшымі з рашэньняў.

Філязофія Rails уключае такія прынцыпы, як:

  • DRY (ад анг. Don't Repeat Youself, што азначае не паўтарайце сябе) – сьцьвярджае, што пісаць шматкроць адзін і той жа код зьяўляецца кепскай рэччу.
  • Convention over configuration (дамоўленасьці па-над наладкамі) – азначае, што ў Rails у шмат якіх выпадках ужо прадвызначана што і як трэба рабіць, замест таго, каб патрабаваць ад распрацоўшчыка вызначаць кожную дробязь (напрыклад, праз файлы канфігурацыі).
  • REST зьяўляецца найлепшым шаблёнам (pattern) для сеціўных праграмаў – арганізацыя праграмаў вакол рэсурсаў і стандартных HTTP-дзеясловаў прыводзіць да найхутчэйшага іх стварэньня.

Архітэктура MVC

Архітэктура MVC у дзеі
Архітэктура MVC у дзеі: жыцьцёвы шлях Rails-запыту

У ядры Rails ляжыць архітэктурны патэрн Мадэль-Вью-Кантролер (ад анг. Model-View-Controller, ці скарочана MVC), перавагамі якога зьяўляюцца:

  • ізаляцыя бізнэс-лёгікі ад інтэрфэйсу;
  • лёгкасьць утрымліваць код DRY;
  • ясна дзе знаходзіцца код таго ці іншага тыпу, што палягчае будучую падтрымку коду.

У адпаведнасьці з гэтым патэрнам адбываецца наступная пасьлядоўнасьць працэдураў:

  1. браўзэр дасылае запыт да вэб-сэрвэру, які перадасылае яго адпаведнаму Rails-кантролеру (файлы ў тэчцы app/controllers/);
  2. кантролер зьвяртаецца да адпаведнай мадэлі (файлы ў тэчцы app/models/), каб атрымаць даныя, неабходныя для адказу на атрыманы запыт;
  3. мадэль адказная за тое, каб сфармаваць належны запыт да базы даных, каб атрымаць адтуль неабходныя даныя;
  4. база вяртае даныя;
  5. мадэль правярае карэктнасьць даных і вяртае іх кантролеру;
  6. кантролер перадае даныя ў шаблён вью (view templates – файлы ў тэчцы app/views/, якія ў агульным выпадку ўяўляюць зь сябе HTML-файлы з убудаваным Ruby-кодам);
  7. шаблён вью фармуе HTML-старонку (ізноў такі ў агульным выпадку, хаця гэта можа быць напрыклад кавалак JavaScript-коду) і перадае яе ў кантролер;
  8. кантролер дасылае вынік браўзэру.

Мадэлі

Мадэль утрымлівае бізнэс-лёгіку і прадстаўляе даныя праграмы. Для прыняцьця рашэньняў мадэль зьвяртаецца да базы даных. Яна адказвае за атрыманьне, стварэньне, зьмяненьне, выдаленьне даных з БД, а таксама сочыць за цэласнасьцю гэтых даных. У выпадку Rails асноўнае выкарыстаньне мадэляў – кіраваньне правіламі атрыманьня інфармацыі з БД. У бальшыні выпадкаў адна мадэль праграмы будзе адпавядаць адной табліцы базы даных.

Больш дэталёва пра мадэлі глядзі ніжэй.

Вью

Вью прадстаўляюць інтэрфэйс праграмы.

Кантролеры

Кантролеры зьяўляюцца «клеям» паміж мадэлямі і вью. У Rails яны адказваюць за апрацоўку запытаў ад браўзэраў, атрыманьне ў адпаведнасьці з тымі запытамі даных з мадэляў, і перадачу гэтых даных у вью для прадстаўленьня карыстальніку.

REST

REST зьяўляецца абрэвіятураў ад ангельскага REpresentational State Transfer (перадача прадстаўнічага стану) і зьяўляецца асновай RESTful архітэктуры. Лічыцца, што ўпершыню гэты архітэктурны прынцып быў сфармуляваны ў доктарскай дысэртацыі Роя Філдзінга. Ён (прынцып) вызначае сеціўную праграму як набор рэсурсаў, доступ да якіх ажыцьцяўляецца праз аднастайныя, прадказуемыя URL і HTTP-дзеясловы GET, PUT, POST і DELETE. Гэтыя URL'ы (HTTP-дзеясловы) вяртаюць пэўнае прадстаўленьне рэсурсу альбо пераводзяць яго ў пэўны стан.

Напр., запыт кшталту:

DELETE /photos/17

будзе зразумелы ў Rails як зьвяртаньне да фота-рэсурсу з ідэнтыфікатарам 17 і пазначэньне пры гэтым пажаданай апэрацыі – выдаленьне гэтага рэсурсу.

REST зьяўляецца натуральным стылем для архітэктуры сеціўных праграмаў іRails рэалізуе яго ў сваім нутры даволі празрыста і пазбаўляе распрацоўшчыка ад неабходнасьці паглыбляцца ў складаныя аспэкты RESTful-архітэктуры.

Кампанэнты Rails

Rails уключае ў сябе шэраг асобных кампанэнтаў:

  • Action Pack
    • Action Controller
    • Action View
    • Action Dispatch
  • Action Mailer
  • Active Model
  • Active Record
  • Active Resource
  • Active Support
  • Railties

Action Pack

Гэта гем, які ўтрымлівае Action Controller, Action View і Action Dispatch – «VC» частку з «MVC».

Action Controller

Гэта кампанэнт, які кіруе кантролерамі. Апрацоўвае запыты да Rails-праграмы, вымае зь іх парамэтры і накіроўвае запыты да адпаведных дзеяў (actions – пад такім агульным паняцьцем разумеюцца мэтады кантролераў). Таксама прадстаўляе такія сэрвісы, як кіраваньне сэсіямі і перанакіраваньнямі, візуалізацыя шаблёнаў.

Action View

Кіруе вью праграмы. Па-змоўчваньні можа ствараць HTML- і XML-вынік. Кіруе шіблёнамі вью, улучна з укладзенымі шаблёнамі (nested templates-спасылка на разьдзел) і часткамі-шаблёнамі (partial templates-спасылка на разьдзел), а таксама ўключае ў сябе ўбудаваную падтрымку AJAX.

Action Dispatch

Адказвае за разводку вэб-запытаў і накіраваньне іх па жаданьні распрацоўшчыка.

Action Mailer

Фрэймворк для пабудовы паштовага сэрвісу. Адказвае за атрыманьне, апрацоўку ўваходных лістоў, а таксама за адсылку простых ці складаных лістоў на базе гнуткіх шаблёнаў.

Active Model

Забясьпечвае інтэрфэйс паміж сэрвісамі Action Pack і ORM-гемамі, як напр. Active Record.

Active Record

Зьяўляецца базай для пабудовы мадэляў. Забясьпечвае незалежнасьць ад пэўнай рэалізацыі базы даных, базавую CRUD-функцыянальнасьць, пашыраныя магчымасьці пошуку, магчымасьці злучаць мадэлі паміж сабой і іншыя.

Active Resource

Прадстаўляе фрэймворк сувязі паміж бізнэс-аб'ектамі і RESTful вэб-сэрвісамі праз CRUD-сэмантыку.

Active Support

Пашыраная бібліятэка дапаможных клясаў Ruby, каторыя выкарыстоўваюцца як ядром Rails, так і праграмай.

Railties

Ядро Rails, якое спалучае разам розныя фрэймворкі і ўбудовы.

Стварэньне новага праекту

Усталяваньне Rails

Перад тым, як ствараць Rails-праект, трэба ўсталяваць уласна Rails (як гем Ruby):

Стварэньне блогу

Пасьля ўсталяваньня Rails можна ствараць новую праграму, напрыклад блог, папярэдне перайшоўшы ў тэчку, прызначаную для Rails-праектаў:

Апошняя каманда створыць шкілет Rails-праекту пад назвай Blog у тэчцы blog. Гэты шкілет уяўляе зь сябе пэўную структуру файлаў і тэчак, аднолькавую для ўсіх Rails-праектаў, што зьяўляецца вялікім плюсам Rails – унівэрсальная структура файлаў і тэчак усіх Rails-праектаў значна палягчае іх падтрымку нават тымі распрацоўшчыкамі, каторыя першапачаткова ня ўдзельнічалі ў іх распрацоўцы. Разгледзем падрабязьней гэтую структуру:

Структура шкілету Rails-праграмы
Файл/Тэчка Прызначэньне
app/ Уласна код, уключаючы мадэлі, вью, кантролеры, хэлперы і актывы (assets).
config/ Наладкі: разводка (routes), база даных, інтэрнацыяналізацыя і інш.
db/ Файлы маніпуляцыяў базай даных. Утрымлівае цяперашнюю схему, файлы міграцыі даных і першапачатковай ініцыялізацыі базы.
doc/ Дакумэнтацыя.
lib/ Модулі бібліятэк.
log/ Логі.
public/ Адзіная тэчка, якая бачна «звонку». У ёй утрымліваецца статычны зьмест і скампіляваныя актывы (assets).
script/ Скрыпты для старту і разгортваньня праграмы, для старту вэб-сэрверу і інш.
test/ Тэсты (юніт-тэсты, fixtures і інш.).
tmp/ Часовыя файлы.
vendor/ Староньні код, звычайна гемы.
README Апісаньне і даведнік па праграме. Павінен утрымліваць інфармацыю як усталёўваць і карыстацца праграмай.
Rakefile Файл утрымлівае batch-каманды, каторыя могуць быць запушчаныя пры дапамозе праграмы rake у тэрмінальным акне. Аналяг build.xml пры выкарыстаньні ant.
Gemfile Апісаньне гемаў, каторыя патрабуюцца праграме.
config.ru Наладкі для Rack-сэрвероў, каторыя выкарыстоўваюцца для старта праграмы.

Усталяваньне патрэбных гемаў

Rails-праграмы па змоўчваньні кіруюць гемамі і іх залежнасьцямі праз Bundler. Як нам ня трэба ніякіх гемаў больш за тыя, што пазначаныя ў змоўчным Gemfile, можна проста запусьціць наступную каманду, каб усталяваць іх:

Наладжваньне базы даных

Мала якія Rails-праграмы могуць абысьціся без базы даных. Аднак, перад тым, як Active Record зможа быць выкарыстаны і праявіць сваё ORM-чараўніцтва, трэба яму сказаць зь якой базай даных будзе весьціся праца і якім чынам зь ёй наладзіць сувязь. Адпаведныя наладкі пазначаюцца ў файле канфігурацыі config/database.yml, які пасьля генэрацыі новай праграмы выглядае наступным чынам:

Гэты файл утрымлівае сэкцыі для канфігурацыі 3-х розных асяродкаў, у якіх Rails можа запускацца па змоўчваньні1:

  • асяродак распрацоўкі (development) выкарыстоўваецца непасрэдна пры распрацоўцы праграмы;
  • тэставы (test) асяродак выкарыстоўваецца пры запуску аўтаматычных тэстаў;
  • вытворчы/працоўны (production) асяродак выкарыстоўваецца пасьля разгортваньня праграмы на агульнадаступных сэрвэрах для мэтавага выкарыстаньня.

Rails пастаўляецца з убудаванай падтрымкай SQLite, якая зьяўляецца «лёгкай» базай даных, не патрабуючай для сваёй працы сэрвэраў (так званая file-based). Яна не патрабуе дадатковых крокаў па сваёй наладцы і запуску, і таму па-змоўчваньні (прыклад вышэй) усе асяродкі будуць наладжаны выкарыстоўваць менавіта яе.

Акрамя SQLite у Rails убудаваная выключная падтрымка яшчэ MySQL і PostgreSQL, а таксама маецца шэраг дадаткаў для падтрымкі іншых базаў даных.

Пры жаданьні, ствараючы новую Rails-праграму, можна пазначыць, каб файл наладкаў быў створаны са змоўчнымі парамэтрамі да іншага тыпу базы даных. Для гэтага трэба скарыстацца опцыяй --database:

Прыклады наладкаў да іншых тыпаў базаў даных:

Стварэньне базы даных

Базы даных адрозныя ад SQLite часьцей за ўсё ствараюцца ўручную адміністратарам/праграмістам, але трэба памятаць, што Rails прадстаўляе мэханізм для аўтаматычнага стварэньня базы даных – пры дапамозе наступнай каманды:

Гэтая каманда створыць базу даных у адпаведным асяродку, узяўшы даныя з файла config/database.yml. Калі ёсьць патрэба сварыць адначасова базы даных для ўсіх асяродкаў, можна скарыстацца варыяцыяй гэтай каманды:

Запуск праграмы

Засталося запусьціць вэб-сэрвер, каб пабачыць стартавую старонку аўтаматычна створанай па-змоўчваньні праграмы:

Каб пабачыць вынік, трэба ў адрасным радку вэб-браўзэра набраць http://localhost:3000. Вы павінны пабачыць наступную старонку:

Start page of Rails default application

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

Кантроль вэрсій з Git

TODO: http://ruby.railstutorial.org/chapters/beginning#sec-version_control

Разгортваньне праграмы ў вытворчым асяродку

TODO: http://ruby.railstutorial.org/chapters/modeling-and-viewing-users-two#sec-heroku_deploy

Праца зь некалькімі рахункамі на Heroku

Гэта не трывіяльная задача, таму што па змоўчаньні гем ад Heroku працуе з адзіным рахункам. Але гэтая задача моцна спрашчаецца пры выкарыстаньні дадатку heroku-accounts.

Дадатак удзяляе літаральна некалькі простых у выкарыстаньні дапаможных камандаў, якія вычарпальна апісаныя на хатняй старонцы дадатку, таму ня буду яшчэ раз спыняцца на апісаньні. Адзінае, што варта адмыслова адзначыць, у код дадатку варта ўнесьці адну зьмену пры жаданьні ўжываць яго ў Windows-асяродку. Гэтая зьмена будзе працаваць толькі пачынаючы з Rails 3-й вэрсіі, але наш даведнік разглядае менавіта гэтую вэрсію, таму скарыстаемся ёй. Праблема тычыцца хатняй тэчкі карыстальніка ў Windows, пэўныя каманды дадатку не працуюць з-за таго, што ў ім выкарыстоўваецца ўласны спосаб вызначэньня гэтай тэчкі, відаць не зусім правільны. Такім чынам, зьмену трэба ўнесьці ў файл <USER_HOME>\.heroku\plugins\heroku-accounts\lib\ext\heroku\command\accounts.rb, у мэтадзе accounts_directory выраз:

трэба зьмяніць наступным чынам:

Хуткая распрацоўка

Вышэй мы разглядалі працэс стварэньня новага праекту, у выніку чаго атрымалі ўнівэрсальны змоўчны каркас праграмы і статычную старонку, каторая адчыняецца па карнявым адрасе. Каб пабачыць нашу праграму ў дынаміцы (напрыклад, адлюстраваць на старонцы тэкст «Вітаю, сусьвет!»), неабходна перш за ўсё выдаліць статычную старонку public/index.html. У Rails існуе шэраг каманд і прыладаў, каторыя паскараюць працэс стварэньня як асобных кампанэнтаў (кантролер, мадэль), гэтак і поўную сукупнасьць усіх неабходных кампанэнтаў для паўнавартаснай працы з пэўным рэсурсам праграмы. Напрыклад, наступным чынам можна стварыць мінімалістычныя кантролер і вью:

Па гэтай камандзе Rails створыць за вас некалькі файлаў, у тым ліку app/views/home/index.html.erb. Гэта шаблён, каторы будзе выкарыстоўвацца для адлюстраваньня вынікаў дзеі index home-кантролеру. Адкрыем гэты шаблён і ўвядзем туды наступны тэкст:

Наступным крокам трэба сказаць Rails’у, якая дзея якога кантролера павінна быць выкананай па карнявым адрасе. Адчынім файл config/routes.rb – гэта файл так званай разводкі1 (ці маршрутызацыі), які ўтрымлівае запісы на адмысловай domain-specific мове, якія вызначаюць да якога кантролеру і якой зь ягоных дзеяў напраўляць уваходныя запыты. Зробім там наступны запіс:

Scaffolding

Акрамя генерацыі асобных кампанэнтаў, прыладай scaffold можна згенерыць поўную сукупнасьць неабходных кампанэнтаў для працы з пэўным рэсурсам. Уявім, што ў нашай праграме павінен існаваць рэсурс допісаў у блогу (Post), экзэмпляры якога карыстальнік можа ствараць, рэдагаваць і выдаляць. Напрыклад, наступная каманда:

Створыць 14 файлаў, неабходныя дадатковыя тэчкі і ўнясе зьмены ў адзін файл:

Файл Прызначэньне
db/migrate/20100207214725_create_posts.rb Міграцыя для стварэньня табліцы ў базе для захаваньня допісаў (у імені вашага файлу будзе іншая часаадзнака).
app/models/post.rb Мадэль допісаў.
test/fixtures/posts.yml Штучныя допісы для тэставых мэтаў.
app/controllers/posts_controller.rb Кантролер допісаў.
app/views/posts/index.html.erb Вью (ці шаблён), які будзе адлюстроўваць сьпіс усіх захаваных допісаў.
app/views/posts/edit.html.erb Вью, у якой будуць рэдагавацца допісы.
app/views/posts/show.html.erb Вью для адлюстраваньня пэўнага допісу.
app/views/posts/new.html.erb Вью для стварэньня новага допісу.
app/views/posts/_form.html.erb Partial, каторы адказвае за візуалізацыю формы рэдагаваньня і стварэньня допісаў.
app/helpers/posts_helper.rb Дапаможныя мэтады апрацоўкі допісаў.
test/unit/post_test.rb Unit-тэсты мадэлі.
test/functional/posts_controller_test.rb Функцыянальныя тэсты кантролеру.
test/unit/helpers/posts_helper_test.rb Unit-тэсты дапаможных мэтадаў.
config/routes.rb Гэты файл будзе адрэдагаваны, каб уключыць апдаведную разводку запытаў.
public/stylesheets/scaffold.css CSS-стылі scaffold-прылады.

Пасьля гэтага трэба запусьціць міграцыю, каб яна стварыла неабходную табліцу ў базе:

А таксама дадаць спасылку да допісаў з нашай галоўнай старонкі (app/views/home/index.html.erb):

Дапаможны мэтад link_to, які даступны да ўсіх вью, створыць спасылку з тэксту і шляху (posts_path), каторыя былі яму перададзены.

Цяпер, калі адкрыць галоўную старонку (http://localhost:3000) і націснуць на спасылку «My Blog», мы пабачым наступную старонку:

Posts index

Гэта змоўчнае адлюстраваньне допісаў. У базе яшчэ няма ніводнага, але калі націснуць на «New post», можна стварыць першы. Пасьля стварэньня допісу, вы пабачыце, што яго можна праглядаць, рэдагаваць і выдаляць, і ўсё гэта было створана аўтаматычна прыладай scaffold.

Мадэль

Створаная пры дапамозе scaffold мадэль (app/models/post.rb) пустая:

аднак базавую сваю функцыянальнасьць (стварэньне, выдаленьне, рэдагаваньне допісаў, запыты да базы) яна ўспадкоўвае ад ActiveRecord::Base. Можам дадаць у яе пэўную праверку даных, каторыя карыстальнік будзе ўводзіць у форму:

Гэты код будзе правяраць ці мае допіс імя і загаловак, каторы пры гэтым павінен утрымліваць мінімум 5 сымбаляў, перад тым, як гэты допіс захаваць у базу.

Адлюстраваньне рэсурсаў

Код, каторы scaffold уставіў у мэтад index кантролеру app/controllers/posts_controller.rb:

адказвае за адлюстраваньне ўсіх допісаў. Выклік Post.all запытаецца ў мадэлі па ўсе допісы, каторыя захаваныя ў базе2. У выніку будзе вернуты масіў допісаў, які захаваецца ў зьменнай экзэмпляру @posts.

Блёк respond_to апрацоўвае як HTML-, так і XML-запыты да гэтай дзеі. Калі ў адрасным радку будзе ўведзена http://localhost:3000/posts.xml, у выніку будуць адлюстраваны ўсе допісы ў XML-фармаце. Для стварэньня HTML-водгуку будзе ўзята вью з app/views/posts/, імя якой адпавядае назьве дзеі (app/views/posts/index.html.erb):

Тут вью пасьлядоўна праходзіцца па ўсім элемэнтам масіву @posts, каб адлюстраваць іх даныя і адпаведныя спасылкі. edit_post_path і new_post_path – дапаможныя мэтады атрыманьня адпаведнага RESTful-шляху.

Мадэлі

Змоўчны спосаб захаваньня даных у Rails – праз базу даных і змоўчным кампанэнтам для гэтых мэтаў зьяўляецца Active Record (рэалізацыя ORM у Rails). Ён прадстаўляе шмат мэтадаў для стварэньня, захаваньня і пошуку аб’ектаў даных і ўсё гэта без неабходнасьці выкарыстоўваць (а адпаведна і ведаць) SQL. Больш таго, пры дапамозе міграцыяў, апісаньне данных можна рабіць на чыстым Ruby, без неабходнасьці ведаць SQL Data Definition Language (DDL). У выніку распрацоўшчык у Rails у агульным выпадку можа абстрагавацца ад асаблівасьцяў і дэталяў сродкаў захаваньня даных, якія будуць ужывацца. То бок у распрацоўшчыцкім асяродку можа выкарыстоўвацца SQLite, у тэставым асяродку – MySQL, а ў вытворчым – PostgreSQL, і на самой праграме гэта ніяк не адаб’ецца.

Яшчэ адзін кампанэнт, які прадстаўляе мадэлі ў Rails – гэта Active Resource. Падрабязьней пра яго глядзі разьдзел Вэб-сэрвісы.

Міграцыі

Стварэньне і зьмены ў структуры даных у Rails робіцца пры дапамозе міграцыяў:

Запуск пазначанай вышэй міграцыі (падкляса ActiveRecord::Migration) праз выкананьне мэтаду up прывядзе да таго, што будзе створана табліца products з радковай калёнкай name і тэкставай калёнкай description. Акрамя гэтага па змоўчаньні будзе створана калёнка першаснага ключу id, нават без яўнага пазначэньня. Таксама будуць створаны калёнкі часаадзнакі created_at і updated_at, зьмест каторых Active Record будзе зьмяняць аўтаматычна. Створаныя міграцыяй зьмены могуць быць адкочаны праз выклік мэтаду down (у дадзеным выпадку табліца products будзе выдалена).

Таксама міграцыямі можна зьмяняць ня толькі структуру, але і самі даныя:

У прыкладзе вышэй да табліцы users будзе дададзена калёнка receive_newsletter, якая па змоўчаньні будзе запаўняцца значэньнямі false, але ў існых запісах табліцы гэтая калёнка будзе запоўнена значэньнем true. У гэтым прыкладзе ёсьць адзін падводны камень – выкарыстаньне клясы мадэлі, чаму гэтага рабіць не пажадана глядзіце разьдзел «Выкарыстаньне мадэляў у міграцыях»

Для базаў даных, каторыя падтрымліваюць транзакцыі (PostgreSQL, SQLite), міграцыі будуць абгорнуты ў транзакцыю. Калі ж база не падтрымлівае транзакцыі (MySQL), тады ў выпадку памылкі зьмены, каторыя адбыліся да памылкі, ня будуць адменены аўтаматычна і іх адкат трэба будзе рабіць «рукамі».

Міграцыі захоўваюцца ў тэчцы db/migrate і маюць выгляд фармату "YYYYMMDDHHMMSS_імя_клясы_міграцыі.rb", дзе "YYYYMMDDHHMMSS" – дата і час міграцыі, пасьля якой праз знак падкрэсьліваньня ідзе імя міграцыі, каторае павінна супадаць зь імем адпаведнай клясы. Напрыклад, файл міграцыі 20080906120000_create_products.rb павінен утрымліваць клясу міграцыі CreateProducts. Дата і час у назьве файла неабходны Rails’у для ідэнтыфікацыі міграцыі. Гэты ідэнтыфікатар нараўне з адзнакамі якія міграцыі ўжо былі выкананыя дазваляе правільна апрацоўваць складаныя сытуацыі пры распрацоўцы праграмы некалькімі распрацоўшчыкамі. Хаця апошняе, натуральна, не пазбаўляе чальцоў каманды ад неабходнасьці ўзгадняць свае дзеяньні.

Пры патрэбе зьмяніць міграцыю, каторая ўжо была выканана, не магчыма проста ўнесьці ў яе зьмены і выканаць ізноў – Rails у адпаведнасьці з запісамі ў сваім журнале пабачыць, што такая міграцыя ўжо выконвалася і нічога ня зробіць у выпадку запуску каманды rake db:migrate. Трэба спачатку адмяніць міграцыю (rake db:rollback), унесьці неабходныя зьмены і потым ізноў выканаць яе.

Пры гэтым памятайце, што калі зьявілася неабходнасьць зьмяніць ужо існую міграцыю – ці то праз памылку, ці то праз новыя акалічнасьці, дазваляецца рабіць гэта толькі ў выпадках, калі яна ўяўляе зь сябе лякальную вэрсію – не запісана яшчэ ў сыстэму кантролю вэрсій для каманднага карыстаньня, ці, што асабліва важна, не была шчэ ўжыта ў вытворчым асяродку. Калі ж міграцыя ўсё ж была ўжыта, лепш стварыць новую міграцыю, у якую прапісаць неабходныя зьмены.

Стварэньне міграцыяў

Пры стварэньні мадэляў ці пры карыстаньні scaffold-генератарамі міграцыі будуць створаны аўтаматычна. Напрыклад, у выніку выкананьня каманды:

будзе створана міграцыя:

t.timestamps будзе дададзена нават, калі гэта не пазначыць у камандзе стварэньня мадэлі.

Калі ж трэба стварыць міграцыю для ўжо існай мадэлі (табліцы ў базе) тады можна скарыстацца генератарам міграцыі:

У выніку выкананьня папярэдняй каманды будзе створана пустая міграцыя:

Калі імя міграцыі адпавядае фарматам "AddXXXToYYY" ці "RemoveXXXFromYYY" і пасьля імені міграцыі ў камандзе ідзе сьпіс палёў зь іх тыпамі, тады ў міграцыю будуць устаўлены выклікі адпаведных мэтадаў: add_column ці remove_column. Напрыклад, пасьля выкананьня:

будзе створана міграцыя:

Састаўленьне міграцыяў

Па спасылцы зьлева можна даведацца пра ўсе мэтады, каторыя даступны ў мэтадах up і down міграцыяў.

Стварэньне табліцаў

Табліцы можна ствараць пры дапамозе мэтаду create_table (па спасылцы зьлева можна даведацца пра ўсе мэтады, каторыя даступны аб’екту, які перадаецца ў блёк мэтаду create_table):

Стварэньне калёнкі ў папярэднім прыкладзе запісана сучасным спосабам, існуе шчэ традыцыйны спосаб:

Па-змоўчаньні мэтад create_table створыць у новай табліцы першасны ключ id. Калі імя першаснага ключа трэба зьмяніць, трэба яўна ўставіць выраз стварэньня гэтага поля і пазначыць для яго опцыю :primary_key.

Тыпы калёнак, каторыя падтрымліваюцца Active Record наступныя:

Тып Active Record Тып SQLite Кляса Ruby
:integer, :primary_key integer Fixnum
:decimal decimal BigDecimal
:float float Float
:string varchar(255) String
:text text String
:binary blob String
:date date Date
:datetime, :timestamp datetime Time
:time time Time
:boolean boolean TrueClass/FalseClass

Гэтыя тыпы будуць аўтаматычна пераўтварацца ў тыпы базы, каторая ўжываецца на цяперашні момант. Напрыклад, у выпадку MySQL тып :string будзе пераўтвораны ў VARCHAR(255). Акрамя гэтага можна пазначаць тыпы, якія не падтрымліваюцца Active Record праз традыцыйны запіс стварэньня калёнак:

Зьмена табліцаў

У папярэднім прыкладзе з табліцы products будуць выдаленыя калёнкі description і name, устаўлена калёнка part_number, да каторай будзе дададзен індэкс, а калёнка upccode будзе перайменавана ў upc_code. Тое ж сама ў традыцыйнай форме будзе:

Дапаможнікі

Існуе шэраг мэтадаў-дапаможнікаў, якія спрашчаюць напісаньне міграцыяў. Напрыклад, згаданы вышэй timestamps, які дадае ў табліцу аб’яўленьні калёнак created_at і updated_at. Яшчэ адзін мэтад-дапаможнік – references, у якога існуе псэўданім belongs_to. Ён дадае апісаньне калёнкі, якая зьяўляецца зьнешнім ключом да іншай табліцы. Наступны прыклад:

дадасьць калёнку category_id адпаведнага тыпу. Зьвярніце ўвагу, што ў мэтад перадаецца імя мадэлі (category), а не імя калёнкі (category_id), пры гэтым _id будзе дададзена аўтаматычна. Яшчэ вельмі істотная заўвага – у выпадку выкананьня гэтага мэтаду будзе проста дададзена калёнка адпаведнай назвы і тыпу, але ня будзе ўстаўлены неабходны constraint праверкі цэласнасьці ключоў. Зрабіць гэта трэба альбо праз выклік адпаведнага «сырога» SQL (глядзі ў прыкладзе ніжэй), альбо праз карыстаньне дадаткам Automatic Foreign Key. Згаданы дадатак у самым простым выпадку лічыць, што калі ў вас ёсьць калёнка customer_id, вы жадаеце, каб быў створаны foreign key constraint на калёнку id табліцы customers:

Мэтад down

Мэтад down міграцыі павінен адкаціць тое, што было зроблена мэтадам up. Іншымі словамі стан базы павінен застацца нязьменным у выніку пасьлядоўнага выкананьня мэтадаў up і down. Прычым апошні павінен рабіць адкат зьменаў у зваротным парадку ў параўнаньні з тым, які быў ў мэтадзе up:

Часам дзеяньні міграцыяў могуць быць незваротнымі – напрыклад, выдаленьне пэўных даных. У такім разе, мэтад down нічога не павінен рабіць, а толькі кідаць выключэньне IrreversibleMigration.

Выкананьне міграцыяў

Rake-каманда db:migrate запускае ўсе міграцыі, якія шчэ не былі выкананыя. Яна ў сваю чаргу запусьціць каманду db:schema:dump, якая зьменіць файл db/schema.rb, каб ён адпавядаў новай структуры базы. Для выкананьня ня проста ўсіх новых міграцыяў, але для пераходу да пэўнага стану, трэба пазначыць адпаведную вэрсію:

Вэрсія – гэта часаадзнакавы прэфікс перад імем міграцыі ў імені файла міграцыі. У выпадку, калі пазначаная вэрсія большая за цяперашнюю, будуць выкананыя мэтады up у тых міграцыяў, якія шчэ не былі выкананыя і чыя вэрсія меншая ці роўная пазначанай у камандзе. Калі ж мы пазначаем вэрсію меншую за цяперашнюю (то бок робім адкат), тады будзе выкананы мэтад down у тых міграцыяў, якія ўжо былі выкананыя і вэрсія якіх большая за пазначаную ў камандзе.

Калі трэба выканаць/адкаціць ня проста ўсе міграцыі да пэўнай вэрсіі, але мэтад up ці down пэўнай адзінай міграцыі, тады трэба карыстацца камандамі db:migrate:up і db:migrate:down:

Прычым Rails сам правярае ці карэктная гэта каманда. То бок, калі пэўная міграцыя ўжо была выканана і мы спрабуем для яе запусьціць каманду db:migrate:up, ці, калі пэўная міграцыя яшчэ не была выканана і мы спрабуем для яе запусьціць каманду db:migrate:down, то ў абодвух выпадках нічога ня будзе зроблена.

Адкат

Для адкату апошняй(-іх) міграцыі(-яў) ёсьць дапаможны мэтад rollback. Наступная каманда зробіць адкат апошняй выкананай міграцыі:

Каб зрабіць адкат некалькіх апошніх міграцыяў дастаткова пазначыць іх колькасьць у парамэтры STEP. Наступная каманда зробіць адкат трох апошніх міграцыяў:

Reset

І яшчэ адна дапаможная каманда: db:reset. Яна выдаліць базу, створыць яе зноўку і загрузіць туды актуальную схему (але гэта ня тое ж самае, што пасьлядоўна выканаць усе міграцыі).

Вывад інфармацыі а хадзе міграцыі

Па змоўчаньні пры выкананьні міграцыі ў кансоль будзе вывадзіцца трасіровачная інфармацыя а хадзе міграцыі. Нешта кшталту:

Існуе шэраг мэтадаў, якія могуць уплываць на гэты працэс:

  • suppress_messages – падаўляе вывад любой трасіровачнай інфармацыі ў сваім блёку;
  • say – выводзіць тэкст, які перадаецца ў якасьці парамэтру;
  • say_with_time – выводзіць тэкст, які перадаецца ў якасьці парамэтру, потым час, які выконваўся яго блёк, і ў выпадку, калі блёк вяртае цэлы лік, лічыць, што гэта колькасьць задзейнічаных міграцыяй радкоў.

Напрыклад, міграцыя:

прывядзе да наступнага вываду:

Калі ж вы жадаеце, каб міграцыя ўвогуле не рабіла ніякага вываду, запускаць яе трэба з опцыяй VERBOSE=false.

Выкарыстаньне мадэляў у міграцыях

Гэтага рабіць вельмі не пажадана! Чаму і якія існуюць рашэньні абыходу праблемы глядзі па спасылцы зьлева.

Адбіткі схемаў

Што такое db/schema.rb і як рабіць міграцыю цалкам усёй схемы глядзі па спасылцы зьлева.

Rake-каманды

У табліцы ніжэй прыводзіцца сьпіс некаторых rake-камандаў, якія тычацца мадэляў, міграцыяў і базаў даных.

Каманда Апісаньне
rake db:create Створыць экзэмпляр базы даных у адпаведным асяродку.
rake db:create:all Створыць экзэмпляры базы даных усіх асяродкаў.
rake db:drop Выдаліць экзэмпляр базы даных у адпаведным асяродку.
rake db:drop:all Выдаліць экзэмпляры базы даных усіх асяродкаў.
rake db:reset Выдаліць экзэмпляр базы, створыць яго наноў і загрузіць у яго схему (зьмест файлу db/schema.rb)
rake db:seed Загрузіць у базу пачатковыя даныя (зьмест файлу db/seeds.rb)
rake db:setup Створыць экзэмпляр базы, загрузіць у яго схему (зьмест файлу db/schema.rb) і загрузіць пачатковыя даныя (зьмест файлу db/seeds.rb)
rake db:version Выводзіць вэрсію актуальнай (апошняй выкананай) міграцыі.
rake db:migrate:status Выводзіць табліцу ўсіх міграцыяў з пазначэньнем вэрсіі міграцыі і ці была яна ўжо выканана.
rake db:migrate Выконвае міграцыі (запускае мэтады міграцыяў up ці change), якія шчэ не былі выкананыя. Камандзе можна перадаваць парамэтар VERSION. Калі значэньне гэтага парамэтру большае за вэрсію актуальнай міграцыі, тады будзе выкананы мэтад up усіх міграцыяў паміж цяперашняй і пазначанай у парамэтры ўключна. Калі ж значэньне парамэтру меншае за актуальную, тады будзе выкананы мэтад down усіх міграцыяў паміж цяперашняй і пазначанай у парамэтры ўключна:
rake db:rollback Адкочвае актуальную міграцыю (запускае мэтад міграцыі down ці робіць аўтаматычны, па пэўным альгарытме адкат мэтаду change). Калі ёсьць патрэба адкаціць адразу некалькі міграцыяў, можна перадаць камандзе парамэтар STEP, у якім пазначыць колькасьць апошніх выкананых міграцыяў, якія павінны быць адкочаны:
rake db:migrate:redo Перавыконвае актуальную міграцыю (пасьлядоўна робіць адкат міграцыі і выконвае яе ізноў  – гл. дзьве каманды вышэй у табліцы). Як і ў выпадку адкочваньня, можна перадаць камандзе парамэтар STEP, у якім пазначыць колькасьць апошніх міграцыяў, якія павінны быць перавыкананы:
rake db:fixtures:load Загрузіць тэставыя даныя (файлы .yml у тэчцы test/fixtures) у базу бягучага асяродку. Калі ёсьць патрэба загрузіць ня ўсе, але толькі пэўныя даныя, можна скарыстацца парамэтрам FIXTURES:

Новыя экзэмпляры

Новы экзэмпляр пэўнай мадэлі можна стварыць пры дапамозе мэтаду new:

А праверыць ці быў гэты экзэмпляр калі-небудзь захаваны ў базу даных (альбо існуе адно ў памяці) можна наступным чынам:

Сачэньне за зьменамі

Часам у праграме трэба ведаць ці былі зроблены зьмены ў аб'екце пасьля яго стварэньня і калі былі, то якія. Пры гэтым выкарыстоўваецца наступная тэрміналёгія: калі адзін ці некалькі атрыбутаў нейкага экзэмпляру былі зьмененыя, яго называюць брудным экзэмплярам; калі брудны экзэмпляр быў захаваны ў базу, ён ізноў становіцца чыстым. Для вызначэньня ці зьяўляецца экзэмпляр брудным выкарыстоўваецца мэтад changed?:

Можна пайсьці далей і запытацца пра пэўныя з атрыбутаў, ці былі яны зьмененыя, і даведацца пра значэньні, якія яны ўтрымлівалі да зьмены:

Пры дапамозе мэтадаў changed і changes можна атрымаць сьпіс зьмененых атрыбутаў і гісторыю іх зьменаў:

УВАГА! Калі атрыбут зьмяняецца без ужываньня апэрацыі прысваеньня, Active Record не ўсьвядоміць зьмены аўтаматычна і трэба кампанэнту дапамагчы зрабіць гэта:

Валідацыя даных

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

У агульным выпадку валідацыю можна рабіць на наступных узроўнях:

  • база даных – канстрэйнты і/ці захаваныя працэдуры. Хаця гэты ўзровень залежыць ад рэалізацыі базы даных і можа ўскладніць працэс тэставаньня праграмы, базы даных звычайна вельмі аптымізаваны пад задачы такога кшталту, і асабліва ў выпадку моцна нагружанага асяродку зьяўляецца найбольш пажаданым месцам для валідацыі;
  • кліенцкі бок – валідацыя ўнутры браўзэра. Для карыстальніка гэты ўзровень зьяўляецца найбольш зручным, таму што водгук ад праграмы прыходзіць амаль імгненна і яму не прыходзіцца доўга чакаць толькі для таго, каб зразумець, што ён увёў нешта ня так. Але адваротны бок гэтага мэдалю ў тым, што па вялікаму рахунку спадзявацца на такую валідацыю ў праграме не выпадае – яна лёгка можа быць падмененая зламысьнікам;
  • Rails-мадэлі – найбольш унівэрсальны ўзровень валідацыі, якая не залежыць ад рэалізацыі базы даных, не можа быць падмененая карыстальнікам, зручная пры тэставаньні і падтрымцы.

Па вялікаму рахунку адна і тая ж валідацыя ў праграме можа быць рэалізавана на ўсіх трох узроўнях. Але ў межах гэтага даведніку разгледзім больш падрабязна валідацыю толькі на ўзроўні Rails-мадэляў. Напрыклад, наступны код будзе прадухіляць захаваньне/абнаўленьне такіх экзэмпляраў клясы Video, у якіх атрыбуты title і embeded не запоўненыя:

Калі ўбудаваных валідатараў не дастаткова, каб рэалізаваць патрэбную валідацыю, можна напісаць уласны валідатар:

Мэтад validate выклікае мэтад-валідатар, імя якога было яму перададзена. Апошні ў сваю чаргу робіць патрэбныя праверкі і ў выпадку, калі экзэмпляр не праходзіць валідацыю, дадае ў яго калекцыю памылак адпаведнае паведамленьне з адпаведным ключом (embeded у прыкладзе вышэй).

Калі адбываецца валідацыя?

Валідацыя ў мадэлі адбываецца непасрэдна перад выклікам адпаведных SQL INSERT... альбо UPDATE... у залежнасьці ад таго, гэта новы экзэмпляр ці ўжо існуючы. Але валідацыю запускаюць ня ўсе мэтады мадэлі, якія прыводзяць да захаваньня экзэмпляру ў базе даных. Мэтады, якія запускаюць валідацыю:

  • create
  • create!
  • save
  • save!
  • update
  • update_attributes
  • update_attributes!

Прычым варыянты мэтадаў з клічнікам ў выпадку неваліднага экзэмпляру кідаюць exception, а астатнія мэтады вяртаюць false (save і update_attributes), альбо сам экзэмпляр (create і update).

Мэтады, якія НЕ запускаюць валідацыю, і, адпаведна, экзэмпляр да якога яны ўжываюцца, будзе захаваны ў базу незалежна ад таго валідны ён ці не, а таму павінны выкарыстоўвацца з асаблівай абачлівасьцю:

  • decrement!
  • decrement_counter
  • increment!
  • increment_counter
  • toggle!
  • touch
  • update_all
  • update_attribute
  • update_column
  • update_counters

Таксама вышэйзгаданы мэтад save не запусьціць валідацыю, калі будзе выкліканы з аргумэнтам :validate => false (трэба ўжываць з асьцярогай!):

valid? і invalid?

Rails унутры сябе для праверкі валіднасьці выкарыстоўвае мэтады valid? і invalid?, якія могуць быць выкарыстаныя і на ўласныя мэты:

Пасьля таго, як была выклікана валідацыя і было выяўлена, што экзэмпляр не валідны, усе паведамленьні пра адпаведныя памылкі даступныя праз мэтад errors, які вяртае хэш:

Убудаваныя валідатары

Мадэлі ў Rails маюць шэраг убудаваных валідатараў, кожны зь якіх мае дзьве формы запісу – поўную:

... і скарочаную:

Пераважнай зьяўляецца поўная форма, таму што пры гэтым можна аб'ядноўваць некалькі валідатараў у адным радку.

Валідатарам можна перадаваць парамэтры (опцыі), :presence => true у прыкладзе вышэй. Акрамя спэцыфічных для кожнага з валідатараў, ёсьць шэраг парамэтраў, характэрных для ўсіх іх:

  • :on – вызначае калі павінна адбыцца валідацыя. Магчымыя значэньні: :save (змоўчнае; захаваньне экзэмпляру незалежна новы ён ці не), :create (толькі пры захаваньні новага экзэмпляру) і :update (толькі пры апдэйце ўжо існага экзэмпляру).
  • :message – вызначае паведамленьне ў выпадку, калі валідацыя не прайшла. Для кожнай з валідацыі існуе змоўчнае паведамленьне, якое будзе выкарыстана, калі гэты парамэтар не пазначаны.
  • :if – пазначае мэтад, працэдуру, альбо чараду для выкананьня, каб вызначыць ці павінна адбыцца валідацыя. Напрыклад:
  • :unless – пазначае мэтад, працэдуру, альбо чараду для выкананьня, каб вызначыць ці павінна валідацыя быць праігнаравана.
  • :strict – калі пазначаны гэты парамэтар са значэньнем true (змоўчным зьяўляецца значэньне false), альбо выкарыстоўваецца мэтад validates! (з клічнікам), валідацыя лічыцца строгай (ня можа быць выпраўленая карыстальнікам) і ў выпадку, калі яна не прайшла, замест запісу адпаведнага паведамленьня ў атрыбут мадэлі errors будзе кінуты эксэпшн ActiveModel::StrictValidationFailed.

Ніжэй асобна разгледзім кожны з убудаваных валідатараў больш дэталёва.

validates_acceptance_of

Правярае ці быў абраны пэўны чэкбокс (у агульным выпадку) пры сабміце формы. Звычайна гэтая валідацыя выкарыстоўваецца, калі карыстальнік павінен згадзіцца з умовамі сэрвісу, пацьвердзіць прачытаньне нейкага тэксту ці ў іншых падобных выпадках. Часта факт «прыняцьця» правяраецца толькі ў момант сабміту формы і не маецца патрэбы захоўваць гэтую інфармацыю ў базе даных, таму ў выпадку адсутнасьці адпаведнага атрыбуту мадэлі валідатар створыць віртуальны атрыбут:

Чэкбокс для гэтага прыкладу можа быць сканструяваны наступным чынам:

Дадатковыя парамэтры:

  • :accept – вызначае значэньне, якое будзе лічыцца за «прыняцьце» (змоўчным зьяўляецца значэньне "1"):
  • :allow_nil – прапусьціць валідацыю, калі парамэтар роўны nil. Змоўчнае значэньне – true.

Змоўчны тэкст паведамленьня для гэтага валідатара: "must be accepted".

validates_confirmation_of

Валідацыя зручна для праверкі значэньняў, якія на вью павінны быць уведзеныя карыстальнікам двойчы для выключэньня памылкі ўводу, напрыклад, значэньне паролю ці адрасу электроннай пошты:

адпаведнае вью можа выглядаць наступным чынам:

Аднак трэба памятаць, што гэтая валідацыя спрацуе толькі, калі email_confirmation ня nil. Для запуску валідацыі ў любым выпадку, незалежна ад значэньня атрыбуту email_confirmation, трэба дадаць валідацыю абавязковасьці:

Змоўчны тэкст паведамленьня для гэтага валідатара: "doesn’t match confirmation".

validates_exclusion_of

Правярае, каб атрыбут мадэлі не прымаў значэньні з пэўнага шэрагу:

Дадатковыя парамэтры:

  • :allow_blank – прапусьціць валідацыю, калі парамэтар не запоўнены (роўны nil альбо пустой чарадзе напрыклад). Змоўчнае значэньне – false.
  • :allow_nil – прапусьціць валідацыю, калі парамэтар роўны nil. Змоўчнае значэньне – false.
  • :in (які мае аліас :within) – вызначае шэраг значэньняў для выключэньня.

Змоўчны тэкст паведамленьня для гэтага валідатара: "is reserved".

validates_format_of

Правярае, каб значэньне атрыбуту мадэлі адпавядала (альбо наадварот, НЕ адпавядала) пэўнаму рэгулярнаму выразу:

Дадатковыя парамэтры:

  • :allow_blank – прапусьціць валідацыю, калі парамэтар не запоўнены (роўны nil альбо пустой чарадзе напрыклад). Змоўчнае значэньне – false.
  • :allow_nil – прапусьціць валідацыю, калі парамэтар роўны nil. Змоўчнае значэньне – false.
  • :with – рэгулярны выраз, якому павінна адпавядаць значэньне атрыбуту. Замест самога рэгулярнага выразу можа стаяць працэдура (лямбда), якая вяртае рэгулярны выраз дынамічна.
  • :without – рэгулярны выраз, якому НЕ павінна адпавядаць значэньне атрыбуту. Замест самога рэгулярнага выразу можа стаяць працэдура (лямбда), якая вяртае рэгулярны выраз дынамічна.

Змоўчны тэкст паведамленьня для гэтага валідатара: "is invalid".

Прывядзем дадатковыя прыклады:

validates_inclusion_of

Правярае, каб атрыбут мадэлі прымаў значэньні толькі з пэўнага шэрагу:

Дадатковыя парамэтры:

  • :allow_blank – прапусьціць валідацыю, калі парамэтар не запоўнены (роўны nil альбо пустой чарадзе напрыклад). Змоўчнае значэньне – false.
  • :allow_nil – прапусьціць валідацыю, калі парамэтар роўны nil. Змоўчнае значэньне – false.
  • :in (ці :within) – вызначае шэраг значэньняў, якія можа прымаць атрыбут.

Змоўчны тэкст паведамленьня для гэтага валідатара: "is not included in the list".

validates_length_of (ці validates_size_of)

Правярае, каб атрыбут мадэлі прымаў значэньні пэўнай даўжыні (роўна, больш/менш, альбо дыяпазону даўжынь):

Дадатковыя парамэтры:

  • :allow_blank – прапусьціць валідацыю, калі парамэтар не запоўнены (роўны nil альбо пустой чарадзе напрыклад). Змоўчнае значэньне – false.
  • :allow_nil – прапусьціць валідацыю, калі парамэтар роўны nil. Змоўчнае значэньне – false.
  • :in (ці :within) – вызначае дыяпазон даўжынь атрыбуту.
  • :is – вызначае дакладную даўжыню атрыбуту.
  • :maximum – вызначае максымальную даўжыню атрыбуту.
  • :minimum – вызначае мінімальную даўжыню атрыбуту.
  • :too_long – значэньне паведамленьня для выпадку, калі даўжыня атрыбуту перавышае максымальна магчымае. Змоўчнае значэньне: "is too long (maximum is %{count} characters)".
  • :too_short – значэньне паведамленьня для выпадку, калі даўжыня атрыбуту меншае за мінімальна магчымае. Змоўчнае значэньне: "is too short (min is %{count} characters)".
  • :tokenizer – вызначае якім чынам чарада атрыбуту павінна быць разьбітая для падліку яе даўжыні. Напрыклад, у выпадку :tokenizer => lambda { |str| str.scan(/\w+/) } за даўжыню будзе лічыцца колькасьць словаў у чарадзе. Змоўчнае значэньне: lambda { |value| value.split(//) }, пры якім за даўжыню будзе лічыцца колькасьць сымбаляў у чарадзе.
  • :wrong_length – значэньне паведамленьня для выпадку, калі даўжыня атрыбуту адрозьніваецца ад дакладнай даўжыні, пазначанай ў парамэтры :is. Змоўчнае значэньне: "is the wrong length should be %{count} characters)".

Для вызначэньня агульнага (для ўсіх выпадкаў) паведамленьня як і звычайна можна выкарыстоўваць парамэтар :message.

validates_numericality_of

Правярае, каб атрыбут мадэлі прымаў толькі лічбавыя значэньні:

Дадатковыя парамэтры:

  • :allow_nil – прапусьціць валідацыю, калі парамэтар роўны nil. Змоўчнае значэньне – false.
  • :equal_to – вызначае, што значэньне атрыбуту павінна быць роўнае пазначанаму. Змоўчнае значэньне паведамленьня: "must be equal to %{count}".
  • :even – вызначае, што значэньне атрыбуту павінна быць цотным. Змоўчнае значэньне паведамленьня: "must be even".
  • :greater_than – вызначае, што значэньне атрыбуту павінна быць больш за пазначанае. Змоўчнае значэньне паведамленьня: "must be greater than %{count}".
  • :greater_than_or_equal_to – вызначае, што значэньне атрыбуту павінна быць больш альбо роўнае пазначанаму. Змоўчнае значэньне паведамленьня: "must be greater than or equal to %{count}".
  • :less_than – вызначае, што значэньне атрыбуту павінна быць менш за пазначанае. Змоўчнае значэньне паведамленьня: "must be less than %{count}".
  • :less_than_or_equal_to – вызначае, што значэньне атрыбуту павінна быць менш альбо роўнае пазначанаму. Змоўчнае значэньне паведамленьня: "must be less than or equal to %{count}".
  • :odd – вызначае, што значэньне атрыбуту павінна быць няцотным. Змоўчнае значэньне паведамленьня: "must be odd".
  • :only_integer – вызначае, што значэньне атрыбуту павінна быць толькі цэлым лікам. Змоўчнае значэньне – false. Змоўчнае значэньне паведамленьня: "must be whole number".

Змоўчны тэкст паведамленьня для астатніх выпадкаў: "is not a number".

validates_presence_of

Правярае, каб атрыбут быў не пустым (быў запоўненым):

У выпадку, калі трэба праверыць ці запоўненая асацыяцыя (зьвязаная запіс), трэба правяраць наяўнасьць не самой асацыяцыі, а зьнешняга ключа да яе:

Улічваючы, што false.blank? верне значэньне true, правяраць запоўненасьць булевых атрыбутаў трэба інакш:

Змоўчны тэкст паведамленьня для гэтай валідацыі: "can’t be empty".

validates_uniqueness_of

Правярае, каб атрыбут меў унікальнае значэньне (сярод усіх запісаў ці па дадатковай умове):

Дадатковыя парамэтры:

  • :case_sensitive – вызначае ці з улікам рэгістру (значэньне true) рабіць праверку унікальнасьці. Змоўчнае значэньне – true.
  • :scope – пазначае дадатковы атрыбут, які будзе ўлічвацца ў вызначэньні ўнікальнасьці (каб зьменшыць «маштаб» унікальнасьці):

Змоўчны тэкст паведамленьня для гэтай валідацыі: "has already been taken".

Уласныя валідатары

Акрамя ўбудаваных валідатараў, калі яны ня здольныя вырашыць пастаўленую задачу, можна скарыстацца уласнымі.

Валідацыя атрыбутаў

Уласная валідацыя асобных атрыбутаў магчымая, па-першае, праз стварэньне клясаў-валідатараў, спадчыньнікаў ад ActiveModel::EachValidator:

Мэтад validate_each гэтага валідатару ў якасьці парамэтраў прымае сам экзэмпляр (record), імя атрыбуту (attr) і ягонае значэньне (value). Зьвярніце ўвагу як пазначаецца валідатар: :email => true, а імя валідатара пры гэтым EmailValidator. Таксама зьвярніце ўвагу, як у апошнім прыкладзе камбінуюцца убудаваны і ўласны валідатары.

Акрамя гэтага для валідацыі атрыбутаў можна скарыстацца макрасам validates_each, якому перадаецца ліст атрыбутаў для праверкі і блёк, які прымае тыя ж парамэтры record, attr і value:

Валідацыя экзэмпляраў

Для праверкі цалкам усяго экзэмпляру можна скарыстацца макрасам validates_with:

Зьвярніце ўвагу на тое, што паведамленьні аб памылцы, дададзеныя ў хэш errors з ключом :base адносяцца не да пэўнага атрыбуту, але да ўсяго экзэмпляру.

У валідатары акрамя стандартных можна перадаваць дадатковыя парамэтры, доступ да якіх у клясе валідатара будзе магчымы праз хэш options:

Мэтады-валідатары

Таксама ўласную валідацыю можна стварыць праз звычайны мэтад мадэлі:

Умоўная валідацыя

Як ужо адзначалася вышэй, кожны з валідатараў можа прымаць парамэтры :if і :unless, якія ўплываюць на тое, пры якіх умовах валідатары будуць выкананыя ці праігнараваныя. Значэньнем гэтых парамэтраў можа быць сымбаль, які павінен адпавядаць імені аднаго з мэтадаў:

...альбо сымбальная чарада, якая павінна ўтрымліваць валідны Ruby-код (выкарыстаньне варта абмяжоўваць толькі вельмі кароткімі ўмовамі):

...альбо аб'ект Proc, які будзе ўтрымліваць код неабходнай умовы:

Калі патрэбна, каб некалькі валідатараў спрацоўвалі па адной і той жа умове, можна скарыстацца макрасам with_options:

Паведамленьні аб памылках валідацыі

Атрыбут мадэляў errors зьяўляецца экзэмплярам клясы ActiveModel::Errors і ўтрымлівае ўсе паведамленьні аб памылках валідацыі:

Мэтад errors[] верне кантэйнэр паведамленьняў аб памылках для пэўнага атрыбуту:

Мэтад add атрыбуту errors, дазваляе дадаваць новыя паведамленьні аб памылках валідацыі, а мэтад clear таго ж атрыбуту робіць кантэйнэр паведамленьняў пустым. Мэтады full_messages і to_a кантэйнэру вярнуць усе паведамленьні аб памылках у форме, у якой яны могуць быць прадстаўленыя карыстальніку.

Акрамя паведамленьняў аб памылках для пэўных атрыбутаў, errors утрымлівае паведамленьні аб памылках, якія адносяцца да ўсяго экзэмпляру мадэлі, пад адмысловым ключом :base.

Зваротныя выклікі

Зваротныя выклікі – гэта пэўныя кавалкі коду, якія выклікаюцца ў пэўныя моманты жыцьцёвага шляху экзэмпляраў мадэляў. Пры дапамозе зваротных выклікаў магчыма выконваць нейкі код кожны раз, калі экзэмпляр ствараецца, загружаецца, захоўваецца, абнаўляецца, праходзіць валідацыю ці выдаляецца.

У якасьці зваротных выклікаў могуць выкарыстоўвацца звычайныя мэтады:

... альбо блёкі, калі гэта вельмі кароткі фрагмэнт коду (1-2 радкі):

Лічыцца добрай практыкай мэтады, якія ўжываюцца як зваротныя выклікі, рабіць private ці protected.

Тыпы зваротных выклікаў

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

Стварэньне аб'екту

  • before_validation
  • after_validation
  • before_save
  • around_save
  • before_create
  • around_create
  • after_create
  • after_save

Абнаўленьне аб'екту

  • before_validation
  • after_validation
  • before_save
  • around_save
  • before_update
  • around_update
  • after_update
  • after_save

Выдаленьне аб'екту

  • before_destroy
  • around_destroy
  • after_destroy

after_initialize і after_find

Зваротны выклік after_initialize выклікаецца кожны раз, калі экзэмпляр ствараецца ў памяці кампутара – альбо праз наўпроставае ініцыіраваньне (выклік мэтаду new), альбо праз загрузку яго з базы даных.

Зваротны выклік after_find выклікаецца кожны раз, калі Active Record вычытвае запіс з базы даных. Ён выклікаецца да выкліку after_initialize, калі абодва зарэгістраваныя:

Калі выконваюцца зваротныя выклікі

Наступныя мэтады мадэляў прыводзяць да запуску адпаведных зваротных выклікаў:

  • create
  • create!
  • decrement!
  • destroy
  • destroy_all
  • increment!
  • save
  • save!
  • save(:validate => false)
  • toggle!
  • update
  • update_attribute
  • update_attributes
  • update_attributes!
  • valid?

Наступныя мэтады мадэляў прыводзяць да запуску зваротнага выкліку after_find:

  • all
  • first
  • find
  • find_all_by_attribute
  • find_by_attribute
  • find_by_attribute!
  • last

Зваротны выклік after_initialize запускаецца кожны раз, калі ў памяці кампутара ствараецца экзэмпляр мадэлі.

Наступныя мэтады мадэляў НЕ прыводзяць да запуску адпаведных зваротных выклікаў:

  • decrement
  • decrement_counter
  • delete
  • delete_all
  • find_by_sql
  • increment
  • increment_counter
  • toggle
  • touch
  • update_column
  • update_all
  • update_counters

Адкат транзакцыі

Усе валідатары і зваротныя выклікі, якія тычыцца пэўнай каманды мадэлі, зьмяшчаюцца ў чараду для выкананьня. Гэтая чарада абгортваецца транзакцыяй базы даных (калі база падтрымлівае транзакцыі). У выпадку, калі before-выклік вяртае false ці кідае выключэньне, уся транзакцыя будзе адкочаная. Але after-выклік прывядзе да адкату толькі ў выпадку кіданьня выключэньня.

Умоўныя выклікі

Як і ў выпадку валідатараў выкананьне зваротных выклікаў можна абстаўляць пэўнымі ўмовамі. Праз падабенства ўжываньня з валідатарамі падрабязна спыняцца ня будзем, а проста прывядзем шэраг прыкладаў:

Асацыяцыі

Састаўленьне запытаў

Вью

Вью – гэта тое, што карыстальнік праграмы бачыць і чаго «кранаецца». У агульным выпадку вью адлюстроўвае даныя мадэлі альбо формы, аднак можа вывадзіць і XML для RSS-рыдэраў ці JSON для пэўнага API.

Rails прадстаўляе гэты прэзэнтацыйны ўзровень пры дапамозе кампанэнта Action View, які ўключае сыстэму шаблёнаў, якая завецца embedded Ruby (ERB) і выдатна падыходзіць для стварэньня HTML-дакумэнтаў:

Пры гэтым код у тэгах <% … %> апрацоўваецца, аднак не выводзіцца ў дакумэнт (звычайна так запісваюцца ўмовы і цыклы). Код жа ў тэгах <%= … %> апрацоўваецца і яго вынік выводзіцца ў выніковы дакумэнт. У выніку апрацоўкі шаблёну з папярэдняга прыкладу будзе сфармаваны прыкладна такі дакумэнт:

distance_of_time_in_words_to_now – ідзін з дапаможных мэтадаў, якія ўключае ў сябе Action View.

Макеты і візуалізацыя ў Rails

Дапаможнікі формаў

Formtastic gem: https://github.com/justinfrench/formtastic

SimpleForm gem: https://github.com/plataformatec/simple_form

Кантролеры

Кампанэнт Action Controller кіруе жыцьцёвым цыклам Rails-запытаў: прымае HTTP-запыты, атрымлівае даныя з мадэляў і візуалізіруе вью. Для спрашчэньня працы распрацоўшчыка ён прадстаўляе аўтаматычнае лагіраваньне, benchmarking, кэшаваньне, кіраваньне сэсіямі і cookies, а таксама іншыя цікавыя магчымасьці як фільтры, якія выклікаюць нейкі код да дзеі ці пасьля яе, што вельмі зручна напрыклад для убудаваньня аўтэнтыфікацыі.

Яшчэ Action Controller аўтаматычна зьвязвае пэўную дзею з адпаведным вью. Разгледзім фрагмэнт тыповага кантролеру:

Калі прыходзіць запыт на URI http://some-app.com/people/index.html мэтад index кантролеру PeopleController будзе шукаць шаблён з такім жа імем і фарматам: index.html.erb

Што яшчэ больш цікава і зручна, гэта што Action Controller можа адказваць тым жа самым мэтадам (дзеяй) на запыты розных фарматаў: на URI http://some-app.com/people/index.json той жа самы мэтад index кантролеру PeopleController з прыкладу вышэй адкажа JSON-дакумэнтам.

Разводка

Які мэтад якога кантролера адказны за чарговы запыт звонку вызначае кампанэнт разводкі (routing) – Action Dispatch. Каб пабачыць усе магчымыя запыты (шляхі), якія праграма наладжана апрацоўваць, можна скарыстацца камандай rake routes:

З гэтай трасіроўкі можна даведацца пра ролю, якую граюць HTTP-выказьнікі ў працэсе разводкі: адзін і той жа шлях /videos будзе накіраваны для апрацоўкі ў розныя мэтады кантролеру VideosController у залежнасьці ад таго быў выкарыстаны выказьнік GET альбо POST. У аснове такога падыходу ляжыць рэалізацыя ідэі RESTful-разводкі, якая між іншым вызначае відавочнасьць і прадказуемасьць выкарыстоўваемых шляхоў. Напрыклад, HTTP-запыт DELETE, дасланы па шляху /videos/1, будзе азначаць запыт на выдаленьне відэа-запісу з ID роўным 1. Як вынікае з апошняга сьцьверджаньня :id-частка у шляху зьяўляецца замяшчальнікам рэальнага ID экзэмпляру.

Запісваецца разводка праграмы ў файле config/routes.rb. Для вызначэньня ўсіх тых шляхоў, якія былі выведзены ў трасіроўцы вышэй, і якія зьяўляюцца змоўчнымі для Rails-праграмы дастаткова ўсяго аднаго радку ў гэтым файле разводкі:

Гэты радок зьяўляецца нічым іншым, як выклікам мэтаду, які наладжвае стандартную RESTful-разводку для відэа-рэсурсаў праграмы.

Парамэтры

Часам у кантролерах трэба мець доступ да даных, пераданых карыстальнікам, ці да іншых парамэтраў праграмы. Існуе 2 віды парамэтраў, даступныя ў любой сеціўнай праграме. Першыя – дасылаемые ў складзе URL'а (query string parameters). Гэтыя парамэтры пазначаюцца ў адрасным радку праз пытальнік пасьля ўласна адрасу. Другі від парамэтраў перадаецца як частка POST-запыту і зьяўляецца звычайна данымі, каторыя карыстальнік увёў у HTML-форму. Нягледзячы на дзьве розныя прыроды гэтых парамэтраў, Rails не падзяляе іх і прадстаўляе аднолькавы да іх доступ – праз Hash-зьменную params:

Хэшы і масівы ў якасьці парамэтраў

У якасьці парамэтраў могуць быць ня толькі дыскрэтныя значэньні, але і хэшы ды масівы. Каб пазначыць, што ў якасьці парамэтру перадаецца масіў, трэба да імені парамэтру дадаць "[]":

У папярэднім прыкладзе значэньне params[:ids] будзе масіў ["1", "2", "3"].

Каб пазначыць, што парамэтар – хэш, трэба ў квадратных дужках пазначыць яшчэ імя ключа:

Калі пазначаная форма будзе дасланая, значэньне params[:client] будзе {"name" => "Acme", "phone" => "12345", "address" => {"postcode" => "12345", "city" => "Carrot City"}}. Зьвярніце ўвагу на наяўнасьць у дадзеным прыкладзе укладзенага хэшу params[:client][:address].

Парамэтры разводкі

Хэш params акрамя іншага заўсёды будзе ўтрымліваць значэньні ключоў :controller і :action, пры гэтым пераважным спосабам атрыманьня адпаведных значэньняў зьяўляюцца мэтады controller_name і action_name. Іншыя парамэтры, якія вызначаюцца разводкай, як напрыклад :id, таксама будуць даступныя. Напрыклад, нам патрэбна вывадзіць сьпіс актыўных і неактыўных кліентаў, тады можна вызначыць разводку наступным чынам, уключыўшы ў яе статус кліента:

У гэтым выпадку, калі карыстальнік набірае ў адрасным радку /clients/active, значэньнем params[:status] будзе "active". Адпаведна, калі спрацуе гэтая разводка, params[:foo] будзе ўтрымліваць значэньне "bar" (гэтак жа сама, калі б парамэтар быў перададзены як query string parameter).

Змоўчныя

У Rails маецца мэханізм, які дазваляе пазначыць парамэтры, каторыя будуць ужывацца пры кожным запыце да пэўнага ці да ўсіх кантролераў – пры дапамозе мэтаду default_url_options:

Cookies

Сеціўная праграма можа захоўваць невялікія аб’ёмы інфармацыі (да 4-ох кілябайтаў) на кліенцкім баку праз cookie браўзэраў, каторыя захоўваюцца пакуль ваша праграма ці сам карыстальнік ня выдаліць іх адтуль. Rails забяспечвае доступ да cookie праз мэтад cookies, праца зь якім, як і ў выпадку з session, мае выгляд працы з хэшамі:

У адрозьненьні ж ад працы з сэсіямі, каб выдаліць пэўнае значэньне з cookie, недастаткова пазначыць у якасьці новага значэньня nil, але трэба карыстацца выклікам кшталту cookies.delete(:key).

Фільтры

Спраўджаньне ўмоваў дзеі

Бясьпека

Techniques to Secure Your Website with Ruby On Rails (Part 1)

Кожны фрэймворк распрацоўкі сеціўных праграм прадстаўляе распрацоўшчыку шэраг магчымасьцяў для ўмацаваньня бясьпекі ствараемай праграмы. Не выключэньне з гэтага правіла і Rails. Аднак, трэба заўважыць, што бясьпека праграмы не ўсталёўваецца і не падтрымліваецца ў належным стане сама па сабе. У любым выпадку апошняе залежыць ад распрацоўшчыкаў – як яны выкарыстоўваюць фрэймворк, а часам і ад тых мэтадаў, каторымі яны карыстаюцца пры распрацоўцы.

Сэсіі

Па сваёй прыродзе HTTP не мае магчымасьці захоўваць стан – кожны новы запыт робіцца з «чыстага аркуша». Гэта зусім не падыходзіць для зручнай працы сеціўных праграмаў, таму што пры пераходзе да новага адрасу праграмы (да новага URL) прыйшлося б штораз пытацца пра імя і пароль карыстальніка, каб ідэнтыфікаваць яго. Для вырашэньня гэтай праблемы быў уведзены мэханізм захаваньня сэсіі карыстальніка цягам усяго часу яго працы ў праграме. Праўда праграма можа ствараць штучныя абмежаваньні на працягласьць сэсій, каб паменшыць магчымыя дзіркі ў бясьпецы праграмы.

Такім чынам, кожнаму карыстальніку праграмы пастаўлена ў адпаведнасьць сэсія – сукупнасьць хэша, які ўтрымлівае спэцыфічныя для сэсіі даныя, і ідэнтыфікатара сэсіі (звычайна 32-сымбальны выпадковы радок), па якому шукаецца адпаведны хэш сэсіі. Ідэнтыфікатар сэсіі дасылаецца да браўзэра, які дасылае яго назад пры наступным запыце. Існуе некалькі спосабаў як абменьвацца ідэнтыфікатарам (праз адрасны радок, схаванае поле формы), але ўсе стандартныя мэханізмы захаваньня сэсіі ў Rails выкарыстоўваюць для гэтага cookie. Сярод згаданых вышэй мэханізмаў захаваньня сэсіі існуюць наступныя:

  • CookieStore – захоўвае даныя на баку кліента, таксама ў cookie, як і ўласна ідэнтыфікатар.
  • DRbStore – захоўвае даныя ў DRb-сэрвэры3.
  • MemCacheStore – захоўвае даныя ў memcached4.
  • ActiveRecordStore – захоўвае даныя ў базе праз Active Record5

Усе пазначаныя мэханізмы акрамя першага захоўваюць даныя сэсіі на баку сэрвэра (ці то ў табліцы базы, ці то ў памяці ці іншым якім чынам), і таму зьяўляюцца больш бясьпечнымі з таго пункту гледжаньня, што зламысьнік не можа падмяніць гэтыя даныя. Але і патрабуюць дадатковыя высілкі на наладжваньне. Змоўчны мэханізм (CookieStore) не патрабуе ўвогуле ніякіх наладкаў і можа быць адразу ж выкарыстаны. Ён троху падгружае сеткавы трафік, таму што даныя сэсіі перадаюцца з кожным запытам, і, тэарэтычна, менш бясьпечны, таму што даныя сэсіі захоўваюцца на кліенцкім баку. Зламысьнік можа атрымаць да іх доступ, прачытаць і падмяніць. Але, па-першае, Rails прадухіляе магчымасьць падмяніць іх, праз крыптаграфічную подпіс. Па-другое, проста ня трэба захоўваць у сэсіі крытычную інфармацыю, неадпаведнае выкарыстаньне каторай можа падарваць бясьпеку праграмы. Акрамя гэтага існуе надбудова EncryptedCookieStore, якая дадаткова да подпісу яшчэ і шыфруе ўвесь зьмест cookie.

Пры выкарыстаньні любога з мэханізмаў захаваньня даных сэсіі (пры ўмове, што яны адпаведна наладжаны, акрамя CookieStore, для якога не патрэбна дадатковая наладка) доступ да іх адбываецца даволі празрыста для распрацоўшчыка:

Наладжваньне

Як наладжваць кожны з мэханізмаў захаваньня даных сэсій глядзіце Err The Blog. Тут жа пазначым толькі агульныя асаблівасьці ды тыя зь іх, якія тычацца CookieStore, як больш пажаданага мэханізму.

Які мэханізм ужываць, а таксама ключ сэсіі (імя cookie), які выкарыстоўваецца пры подпісе даных сэсіі, пазначаецца ў файле config/initializers/session_store.rb:

Сакрэтны ключ, які таксама ўжываецца пры подпісе даных, пазначаецца ў файле config/initializers/secret_token.rb6

Ігнараваньне

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

Каб праграма ігнаравала запыты ботаў пры кіраваньні сэсіямі, трэба спачатку мець мэтад, які будзе вызначаць ці гэта бот:

Пасьля гэтага адключаем для іх апрацоўку сэсій:

Бліскаўкі

Хаця й не маюць непасрэдны ўплыў на бясьпеку праграмы, але зьяўляюцца неад'емнай часткай сэсій так званыя бліскаўкі (ад ангельскага flash) – паведамленьні (інфармацыйныя, папярэджваючыя ці аб памылках), час жыцьця якіх – выключна наступны запыт. Адсюль і назва. Праца зь імі падобна да працы з сэсіямі. Разгледзім прыклад выхаду карыстальніка з праграмы. Адпаведны кантролер можа пазначыць якое паведамленьне паказаць карыстальніку наступным крокам:

Тое ж самае можна зрабіць троху іншым чынам – праз само перанакіраваньне:

Дзея destroy кантролеру LoginsController перанакіроўвае да адрасу root_url, дзе пазначанае паведамленьне павінна быць адлюстравана. Аднак, што рабіць і ўвогуле ці рабіць нешта з гэтым паведамленьнем, залежыць ад кантролера (вью), адказнага за наступны запыт. Павялося, што бліскаўкі адлюстроўваюцца ў макетах праграмы:

Пры такім падыходзе бліскаўкі, пазначаныя папярэднімі дзеямі, будуць аўтаматычна адлюстроўвацца макетамі. У адваротным выпадку імі нічога ня будзе адлюстравана.

Пры неабходнасьці перадаць тыя ж бліскаўкі наступнаму запыту можна скарыстацца мэтадам keep:

flash.now

Часам нейкае паведамленьне трэба адлюстраваць у межах таго ж самага запыту, без перанакіраваньня. Напрыклад, калі пэўная дзея пры памылцы дасылае да іншай дзеі таго ж кантролеру. У гэтым выпадку звычайнымі бліскаўкамі скарыстацца няма магчымасьці, таму што доступ ёсьць толькі да паведамленьняў з папярэдняга запыту. Тады трэба карыстацца flash.now:

Адначасовае множнае прысваеньне

http://guides.rubyonrails.org/security.html#mass-assignment

http://net.tutsplus.com/tutorials/ruby/mass-assignment-rails-and-you/

Ідэнтыфікацыя карыстальніка

authlogic: https://github.com/binarylogic/authlogic, https://github.com/binarylogic/authlogic_example, http://www.dixis.com/?p=352, http://www.manu-j.com/blog/add-google-oauth-ruby-on-rails-sites/214/, http://stackoverflow.com/questions/3508494/configuring-username-format-in-authlogic, http://stackoverflow.com/questions/2615372/configuring-authlogic-oauth-with-google, http://stackoverflow.com/questions/3454248/configure-authlogic-to-log-in-with-username-or-email

Ruby OAuth: https://github.com/oauth/oauth-ruby

devise: https://github.com/plataformatec/devise, https://github.com/plataformatec/devise/wiki, http://www.tonyamoyal.com/2010/07/28/rails-authentication-with-devise-and-cancan-customizing-devise-controllers/

Аўтарызацыя

CanCan: https://github.com/ryanb/cancan

Падробка запытаў

Абарона

Бясьпечная перадача даных

SSL on Heroku

Rails 3 SSL Deprecation

Rails 3 SSL routing redirects from https to http

How do I force an SSL connection with Rails 3, but only when a user is logged in?

Rails redirect with HTTPS: http://stackoverflow.com/questions/1662262/rails-redirect-with-https

Using SSL in Rails Applications: http://www.buildingwebapps.com/articles/79189-using-ssl-in-rails-applications

Rails and SSL: http://siannopollo.blogspot.com/2007/08/rails-and-ssl-https.html

ssl_requirement: https://github.com/retr0h/ssl_requirement, http://rubygems.org/gems/ssl_requirement

Наладка SSL для WEBrick

Па змоўчаньні стандартны вэб-сэрвер распрацоўшчыцкага асяродку (WEBrick) апрацоўвае толькі http-запыты. Каб «прымусіць» яго апрацоўваць і https-запыты, патрабуецца прыкласьці трохі высілкаў.

Генерацыя сэртыфікату

Першым крокам трэба стварыць сэртыфікат, каторы будзе ўжывацца для шыфраванай перадачы даных. Зробім гэта пры дапамозе бясплатнай прылады OpenSSL. Яна, дарэчы, ідзе ў пастаўцы Git. Таму, калі ў вас ужо ўсталяваны апошні, вы знойдзеце openssl.exe у яго bin тэчцы. Выконваем наступную каманду для стварэньня Request-сэртыфікату і адпаведнага прыватнага ключу:

У працэсе выкананьня будзе заданы шэраг абавязковых (напр. пароль) і неабавязковых (калі вы не жадаеце ўводзіць пэўныя даныя, пастаўце кропку) пытаньняў:

У выніку будуць створаны 2 файлы: server.cert.csr (Request-сэртыфікат) і privkey.pem (прыватны ключ). Вымем зараз ключ для подпісу сэртыфікату (інакш прыйшлося б уводзіць пароль пры ўсталяваньні https-злучэньня):

Гэта створыць файл server.cert.key. Зараз трансфармуем Request-сэртыфікат у падпісаны сэртыфікат:

У выніку атрымаем файл падпісанага сэртыфікату server.cert.crt.

Актывацыя SSL у WEBrick

Зараз створым тэчку cert у карнявой тэчцы адпаведнай Rails-праграмы і перапішам туды файлы server.cert.crt і server.cert.key. Пасьля гэтага трэба зрабіць копію файла rails у тэчцы script, назавем яго rails_ssl. Адкрыем яго і ўставім перад аб’яўленьнем пераменнай APP_PATH наступныя радкі:

Зьвярніце ўвагу на наступныя акалічнасьці. Пе-першае, мы абралі порт (:Port => 3001), які адрозьніваецца ад стандартнага https-порту (443), таму што апошні па змоўчаньні блякуецца файрволам Windows, а ў распрацоўшчыцкім асяродку няма вялікай розніцы які порт абраць. Таксама порт павінен адрозьнівацца ад стандартнага порту WEBrick у Rails (3000), таму што, калі мы жадаем, каб працавалі і http-запыты, і https-запыты, нам трэба будзе запускаць 2 экзэмпляры WEBrick – адзін для апрацоўкі http-запытаў, іншы для апрацоўкі https-запытаў. Гэта можа ня вельмі зграбнае рашэньне праблемы, але даволі простае, таму заплюшчым на гэта вочы. Па-другое, у прыкладзе пазначаныя фіктыўныя шляхі да файлаў сэртыфікату і ключа (/path/to/crt і /path/to/key). Вам трэба будзе зьмяніць іх на сапраўдныя, кшталту d:/projects/abc/cert/server.cert.key. Вуаля! Цяпер трэба ў адным кансольным акне запусьціць сэрвер для http:

а ў іншым кансольным акне – сэрвер для https:

Тэставаньне

Whiny Validation – дапаможны для тэстаў гем, прызначаны для вываду ў лог інфармацыі аб тым, што была памылка валідацыі пэўнай мадэлі. Без гэтага гему (дадатковага логу) часам вельмі складана зразумець чаму падае тэст.

Пошта

Дастаўка электронных лістоў у Rails на аснове шаблёнаў робіцца вельмі падобна на візуалізацыю HTML/ERB вью. Акрамя гэтага кампанэнт Action Mailer дазваляе адказваць на ўваходныя лісты, пераўтвараць уваходныя лісты ў камэнтары на HTML-старонках і іншае.

Лякалізацыя

Tolk – рухавік, які дапамагае перакладчыкам рабіць пераклад праграмы на розныя мовы.

Вэб-сэрвісы

Active Resource дазваляе выкарыстоўваць зьнешні RESTful-API нібы лякальныя рэсурсы (мадэлі) праграмы.

RSS

Каб дадаць у праграму магчымасьць адказваць на запыты RSS-чытальнікаў, дастаткова ў дзею кантролера дадаць яшчэ адзін, адпаведны фармат вью (радок 7):

У якасьці шаблёну можна было б стварыць index.atom.erb і скарыстацца магчымасьцямі ERB для генэрацыі вью. Але Rails мае начыньне, якое больш пасуе для стварэньня XML-дакумэнтаў, якімі зьяўляюцца дакумэнты для RSS-чытальнікаў – гэта Builder-шаблёны (index.atom.builder):

Акрамя стварэньня магчымасьці адказваць на наўпроставыя RSS-запыты, можна ў звычайную HTML-старонку дадаць дадатковы тэг, каб браўзэры самі маглі вымаць інфармацыю пра RSS. Для гэтага ў целе тэгу <head> трэба ўставіць наступнае:

Альбо тое ж самае пры дапамозе Rails-дапаможніку:

Аптымізацыя

HTTP Caching in Ruby with Rails

Маштабіруемасьць

Money in Rails

Money values:

Плацежныя сыстэмы ў Rails

ActiveMerchant – дадатак і gem.

Enlarge your payment, или паранойя платежных систем.

Інтэграцыя з JavaScript

Праблема выкарыстаньня jQuery у Rails. Канфлікты з іншымі фрэймворкамі і шляхі іх разьвязваньня:

RJS, jQuery, Rails:

AJAX:

Rails3: remote links and forms data type with jQuery

Rails jquery-ujs now interactive

jQuery-UI dialog instead of alert for Rails3 data-confirm attribute

Unobtrusive javascript in Rails3

AJAX CRUD using Rails3 and unobtrusive JavaScript.

Іншыя фрэймворкі

«Rails mits Sinatra» – як пры дапамозе Rack аб'яднаць праграму на Rails і на Sinatra, каб яны абедзьве працавалі пад адным сэрвэрам.

CMS

Refinery

Locomotive

Webiva

Radiant

Casein

BrowserCMS

Даведнікі пераехалі на GitHub Pages. Актуальная вэрсія даступная па адрасе: https://yurtsevich.github.io/refs/rails/