Sinatra, по заявлению разработчика, представляет из себя "DSL для быстрого и с минимальными усилиями создания веб-приложений на Ruby"... как водится, быстренько знакомимся с описаниями Sinatra и вообще что такое DSL, открыв соответствующие доки, ну и вперед. Постараемся, чтобы итог сегодняшних наших усилий содержал написанное в парадигме MVC приложение; зачем нам с вами портянка кода, не правда ли? Будем следовать (и сейчас и в будущем) примерно вот такой логике:
├── Gemfile
├── README.md
├── app
│ ├── controllers
│ │ └── application_controller.rb
│ ├── models
│ │ └── model.rb
│ └── views
│ └── index.erb
├── config
│ └── environment.rb
│ └── database.yml
├── config.ru
├── public
│ ├── javascripts
│ ├── stylesheets
│ ├── fonts
├── db
│ └── migrate
│ │ └── 20201006073568_create_first_table.rb
Но, прежде всего, позаботимся об удобстве; автоматически перезагружать среду разработки поможет shotgun, который добавляем в Gemfile (джемы 'require_all' и, конечно, синатра - также не будут лишними):
Gemfile
source "https://rubygems.org"
gem 'sinatra'
gem 'shotgun'
gem 'require_all'
Далее указываем в config.ru, что для старта приложения необходимо запустить ApplicationController:
config.ru
require_relative './config/environment'
run ApplicationController
Остальные настройки:
environment.rb
require 'bundler/setup'
APP_ENV = ENV["RACK_ENV"] || "development"
Bundler.require :default, APP_ENV.to_sym
require 'rubygems'
require 'bundler'
require_rel '../app'
Теперь дело за контроллером. Не мудрствуя лукаво, я прописал в нем два действия (Sinatra определяет действия как методы) для одной-единственной странички, отправляющей данные формы, также определил местонахождение каталога views (по умолчанию Sinatra ищет его рядом с контроллером) и public_dir:
application_controller.rb
class ApplicationController < Sinatra::Base
configure do
set :views, 'app/views'
set :public_dir, 'public'
end
get '/' do
erb :index
end
post '/' do
unless params[:birthday].nil?
arr = BiorhythmsCalc.get_values_and_dates(params[:birthday])
@values = arr[0]
@dates = arr.delete_at(1)
@message = BiorhythmsCalc.alert(params[:birthday])
end
erb :index
end
end
В скобках, это мы с вами делаем счетчик биоритмов, код доступен в гитхабе (Biorhythm-Calculator), демка - на Heroku:
app/models/biorhythms_calc.rb
class BiorhythmsCalc
def self.get_values_and_dates(b)
values = []
[23, 28, 33].each do |x|
values << BiorhythmsCalc.biorhythm_counter(x, todays_date(b))[0]
end
dates = BiorhythmsCalc.biorhythm_counter(x = 23, todays_date(b))[1].map { |e| "`#{e}`" }.join(', ')
[values, dates]
end
def self.biorhythm_counter(*args)
arr1 = []
arr2 = []
(-3..15).each do |x|
arr1 << calculation(x, args[1], args[0])
arr2 << get_date_period(x)
end
[arr1, arr2]
end
def self.calculation(*args)
(Math.sin(2 * Math::PI * BiorhythmsCalc.day_counter(args[0], args[1].to_date) / args[2]) * 100).round(2)
end
def self.get_date_period(x)
Date.today + x
end
def self.day_counter(*args)
Integer(Date.today + args[0] - args[1])
end
def self.todays_date(b)
Date.strptime(b, '%d-%m-%Y')
end
def self.alert(b)
'Today, ' +
Time.new.strftime('%d of %B, %Y').to_s +
', you have lived ' +
BiorhythmsCalc.day_counter(0, todays_date(b)).to_s +
' days.'
end
end
Содержимое файла index.erb (вьюха, в просторечии) возможно глянуть, при необходимости, в моем гитхабе; не буду приводить здесь. Можно даже, при необходимости, склонировать из Github полностью рабочее приложение:
git clone https://github.com/cmirnow/Biorhythm-Calculator.git
Что еще? - если намереваетесь по окончании работы сделать push на Heroku, не помешает добавить:
Procfile
web: bundle exec rackup config.ru -p $PORT
Ну и на этом походу все, run and enjoy:
bundle install #or bundle install --path vendor/bundle
bundle exec shotgun
Комментарии в блоге