Sinatra не піклується про те, як ви організовуєте ваш додаток. На відміну від Rails, Sinatra не накладає ряд серйозних обмежень на структуру ваших додатків. Ви можете покласти все в один файл, або розбити на структуру каталогів. Звичайно, якщо ви розіб'єте на окремі файли, потрібно підключати їх в міру необхідності - у Sinatra немає узгоджень, як в Rails, про те де шукати ці файли.
Моя структура каталогів, вона дуже проста:
/
blog.rb
db/
db.sqlite3
views/
layout.haml
/posts
edit.haml
index.haml
new.haml
show.haml
Я поклав все крім шаблонів в один файл. Таким чином конфігурації, моделі і всі події будуть у файлі blog.rb. Також Sinatra по замовчуванню підхоплює каталог views, який містить шаблони представлень.
Підключаємо необхідні бібліотеки у файлі blog.rb
require 'rubygems'
require 'sinatra'
require 'haml'
require 'dm-core'
require 'dm-timestamps'
require 'dm-migrations'
Конфігурація бази даних
Додамо наступні рядки в файл blog.rb:DataMapper.setup(:default, "sqlite3://#{Dir.pwd}/db.sqlite3")
Це налаштує 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(:title => params[:title], :body => params[:body])
redirect "/posts/show/#{id}"
else
redirect "/posts/edit/#{id}"
end
end
Метод update схожий на 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
Відображає порожню форму для додавання нової статті.
%h1 Write a new post
%form{:method => 'post', :action => "/posts/new"}
%ul
%li#title
%label{:for => 'post_title'} Title:
%br
%input{:type=>'text', :id => 'post_title', :name => 'title'}
%li#body
%label{:for => 'post_body'} Body:
%br
%textarea{:type=>'textarea', :id => 'post_body', :cols => 80, :rows => 5, :name => 'body'}
%input{:type=>'submit', :value => 'New'}
%a{:href => "/posts"}= "< Back"
views/posts/show.haml
Відображає поточну статтю.
%h3= @post.title
%p= @post.body
%a{:href => "/posts"}= "< Back"
views/posts/edit.haml
Відображає форму, заповнену даними поточної статті.
%h1 Edit a post
%form{:method => 'post', :action => "/posts/edit/#{@post.id}"}
%ul
%li#title
%label{:for => 'post_title'} Title:
%br
%input{:type=>'text', :id => 'post_title', :name => 'title', :value => @post.title}
%li#body
%label{:for => 'post_body'} Body:
%br
%textarea{:type=>'textarea', :id => 'post_body', :cols => 80, :rows => 5, :name => 'body'}= @post.body
%input{:type=>'submit', :value => 'Edit'}
%a{:href => "/posts"}= "< Back"
У наступній статті я продовжу розповідь про організацію блогу.
Дякую за увагу!
Немає коментарів:
Дописати коментар