Ця стаття є так би мовити третьою. У двох попередніх ми вже встигли познайомитися з веб-фреймворком Sinatra () та ORM бібліотекою DataMapper (). Прийшов час застосувати ці знання на практиці. Напишемо наш "proof of concept" додаток, використовуючи Sinatra, DataMapper, HAML, SASS. Я вирішив, що ми проведемо наші навчальні заняття за написанням блогу.
Sinatra не піклується про те, як ви організовуєте ваш додаток. На відміну від Rails, Sinatra не накладає ряд серйозних обмежень на структуру ваших додатків. Ви можете покласти все в один файл, або розбити на структуру каталогів. Звичайно, якщо ви розіб'єте на окремі файли, потрібно підключати їх в міру необхідності — у Sinatra немає узгоджень, як в Rails, про те де шукати ці файли.
Моя структура каталогів, вона дуже проста:
Я поклав все крім шаблонів в один файл. Таким чином конфігурації, моделі і всі події будуть у файлі blog.rb. Також Sinatra по замовчуванню підхоплює каталог views, який містить шаблони представлень.
Підключаємо необхідні бібліотеки у файлі blog.rb
Це налаштує DataMapper використовувати SQLite3 і збереже файл БД у каталозі db.
MVC
Концепція MVC дозволяє дозволяє розділити дані, представлення та обробку дій користувача на три окремі компоненти
Модель(Model). Надає дані (зазвичай для Viev), а також реагує на запити від контролера.
Представлення(View). Відповідає за представлення даних користувачеві.
Контролер(Controller). Інтерпретує дані, введені користувачем, та інформує модель і представлення про необхідність відповідної реакції.
Така внутрішня структура в цілому розбиває систему на самостійні частини і розподіляє відповідальність за різні компоненти. Важливо відзначити, що як представлення, так і контролер залежать від моделі. Тоді як модель не залежить ні від контролера, ні від представлення. Це одна з основних переваг такого поділу. Вона дозволяє будувати модель незалежно від візуального представлення, а також створювати кілька різних представлень для однієї моделі.
Модель
В Sinatra модель представляє з себе звичайний клас Ruby.
class Post
include DataMapper::Resource
property :id, Serial
property :title, String
property :body, Text
property :created_at, DateTime
property :published, Boolean, :default => false
end
Після опису Post пишемо:
DataMapper.auto_upgrade!
Цей рядок змусить DataMapper оновлювати структуру БД при змінах нашого класу Post.
Контролер
Одна з цікавих особливостей Sinatra, вам не потрібно створювати цілий клас контролера для простих додатків. Достатньо визначити обробники подій. Додамо необхідні події для нашої моделі Post. Для цього визначимо декілька методів-заглушок. Кожен метод відповідає за певну подію. Створимо базовий набір подій, яким повинен відповідати наш додаток для статей.
Напишемо реалізацію наших методів.
Метод index відображає весь список статей.
get '/posts' do
@posts = Post.all
haml :'posts/index'
end
Тут ми оголошуємо змінну @posts, яка буде доступна з шаблону, де ми і відобразимо наші статті. Вираз Post.all отримує всі статті з бази даних.
Метод show відображає одну статтю. get '/posts/show/:id' do
@post = Post.first(:id => params[:id])
haml :'posts/show'
end Post.first(id => params[:id]) говорить DataMapper знайти статтю відповідну id, переданого в params. params — це об'єкт-контейнер, який дозволяє передавати параметри виклику. Наприклад при виводі списку статей, ви можете клацнути на посилання певної статі і id цієї статті передасться в об'єкті params.
Метод new відображає HTML сторінку з формою для створення нової статті.
get '/posts/new' do
:haml => :'posts/new'
end
Після заповнення полів форми на HTML сторінці, створюємо новий об'єкт в базі даних за допомогою методу create.
post '/posts/new' do
@post = Post.new(:title => params[:title], :body => params[:body])
if @post.save
redirect '/posts'
else
redirect '/posts/new'
end
end
Другий рядок створює новий екземпляр класу Post, заповнений даними, які надіслав користувач за допомогою форми. Наступним рядком ми намагаємося зберегти об'єкт і в разі успіху перенаправляємо на сторінку зі списком статей. Для цього використовується метод redirect, параметр якого встановлено в '/posts'. У випадку невдачі заново відображається сторінка створення нової статті.
Метод edit служить для редагування об'єкта, і дуже схожий на метод show — в обох виходить об'єкт із заданим id, різниця тільки в тому, що форма для show не редагується.
get '/posts/edit/:id' do
@post = Post.first(:id => params[:id])
:haml => :'posts/edit'
end
Метод update викликається після методу edit для оновлення існуючої статті. Цей метод схожий на create, але призначений для оновлення існуючого об'єкта в базі даних.
post '/posts/edit/:id' do
id = params[:id]
@post = Post.first(:id => id)
if @post.update_attributes(:title => params[:title], :body => params[:body])
redirect "/posts/show/#{id}"
else
redirect "/posts/edit/#{id}"
end
end
Метод update_attributes схожий на save, але він не створює новий запис в БД, а тільки оновлює поля. У випадку успіху ми перенаправляємо на метод show, інакше відправляємо знову на редагування.
Реалізуємо метод destroy для видалення статті.
get '/posts/destroy/:id'
post = Post.first(:id => params[:id])
post.destroy!
redirect '/posts'
end
У другому рядку ми знаходимо об'єкт по id і методом destroy! видаляємо його. Далі робимо перенаправлення на index.
Представлення
Створимо відповідні шаблони для візуального представлення даних користувачу.
Всі наші шаблони будуть використовувати один спільний макет. По замовчуванню Sinatra шукатиме його в views/layout.haml.
views/layout.haml
%html
%head
%title My Blog
%meta{"http-equiv" => "Content-Type", :content => "text/html; charset=utf-8"}
%body
#container
= yield
views/posts/index.haml
Відображає колекції статей, кожна з яких містить посилання на операцію іх отримання, оновлення та видалення. А також створення нової статті.
#header
%h1 My blog
%a{:href => "posts/new"}> New Post
#content
- @posts.each do |post|
.container
%h3= post.title.force_encoding('utf-8')
%p= post.body.force_encoding('utf-8')
%p= post.created_at
%a{:href => "posts/show/#{post.id}"}> Show
|
%a{:href => "posts/edit/#{post.id}"}> Edit
|
%a{:href => "posts/destroy/#{post.id}"}> Delete
views/posts/new.haml
Відображає порожню форму для додавання нової статті.
Коментарі (2)
RSS згорнути / розгорнутиmeako
mamantoha
Тільки зареєстровані й авторизовані користувачі можуть залишати коментарі.