一、安装Sinatra
1.1 安装Ruby
1.1.1 RVM安装
(1)首先下载安装xcode,https://itunes.apple.com/us/app/xcode/id497799835?ls=1&mt=12
(2)安装RVM
采用的是curl方式(在mac上没有wget,可以用自带命令curl实现wget的默认功能,wget是下载专用的利器,支持递归,支持断点,更多curl的使用方法如下链接,https://blog.csdn.net/fudesign2008/article/details/7608619), 将会在本地目录下形成文件,即~/.rvm
,相应的命令如下所示:
curl -L https://get.rvm.io | bash -s stable
命令执行后的结果如下所示;
(3)载入 RVM 环境
source ~/.rvm/scripts/rvm
(4)检查一下是否安装正确
输入如下所示的命令,可以得到安装的rvm版本是1.29.4,说明安装成功;
rvm -v
1.1.2 用 RVM 安装 Ruby
(1)列出已知的ruby版本
rvm list known
可以看出来最新的ruby是2.6.0版本,我们选择安装这一版本;
(2)选择现有的rvm版本来进行安装
这里我们选择最新的版本进行安装,如下
rvm install 2.6.0
遇到一个错误,最后没有安装成功;
换一个新的版本2.0.0,尝试重新安装,结果安装成功,相应的过程如下所示
虽然有警告,但是显示安装成功,只是没有安装使用文档;
查询是否ruby已经安装成功,使用命令ruby -v
,和命令gem -v
,查询的结果如下所示,显示ruby的版本是2.0.0,gem版本是2.7.8。
查询已经安装的ruby,
rvm list
卸载一个已安装版本,rvm remove 2.6.0
1.1.3 设置 Ruby 版本
RVM 装好以后,需要执行下面的命令将指定版本的 Ruby 2.0.0设置为系统默认版本,使用的命令如下所示
rvm 2.0.0 --default
要是想更换源,使用如下命令:
删除默认源,gem source -r https://rubygems.org/
增加淘宝镜像,gem source -a https://ruby.taobao.org
验证是否替换成功,gem sources -l
1.2 安装Sinatra
1.2.1 使用Rubygems的方式进行安装,如下所示:
但是遇到了版本过低无法安装的情况,要求ruby版本不能低于2.2.2,如下图所示;
采用继续重新安装ruby2.3.7的版本,如下所示;
安装过程中会自动删除旧版本ruby2.0.0,显示安装成功,同样查询ruby和gem版本,分别是2.3.7和2.7.8,如下所示;
重新进行系统默认ruby版本制定,命令如下所示:
rvm 2.3.7 --default
1.2.2 重新安装Sinatra
显示安装成功,界面如下所示;
二、编写代码
2.1 创建main.rb文件
打开编辑器,输入如下所示的命令格式,然后保存到一个新建的文件夹sinatratest里面;
require 'sinatra'
get '/' do
"Just Do It"
end
2.2 运行代码
打开终端进入siatratest文件,输入命令执行main文件,结果如下所示;
ruby main.rb
打开一个浏览器,输入http://localhost:4567
,即可以打开网站,如下图所示;
输入Ctrl+C,可结束HTTPServer的服务,如下所示;
2.3 使用内嵌模版slim
2.3.1 安装slim模版
使用命令进行安装,结果如下图所示;
gem install slim
2.3.2 重新修改新的main.rb内容
新的代码如下所示,加了slim的模块(还有的模版有ERB, Haml 和 Markaby),
内嵌的模版都是从__END__
之后开始的,其中每一个模版都是以@@
开始;@@layout的视图是自动加载的,@@index视图是依靠slim模块加载完成的
require 'sinatra'
require 'slim'
get '/' do
slim :index
end
__END__
@@layout
doctype html
html
head
meta charset="utf-8"
title Just Do It
link rel="stylesheet" media="screen, projection" href="/styles.css"
/[if lt IE 9]
script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"
body
h1 Just do It
== yield
@@index
h2 myTask
ul.tasks
li Get Milk
重新执行完代码后,打开浏览器,输入之前的网址后,界面如下所示,发生了变化;
记住每一次改变ruby文件内容后,都要使用命令
ruby main.rb
重新启动一下HTTPServer服务。
2.3.3 分割视图到不同的文件里
(1)首先在sintratest文件夹里新建两个文件,分别命名为public(用来放图片和样式文件)和views(用来放各种样式文件),如下图所示。
(2)删除main.rb内容__END__
之后的样式内容,修改后main的内容如下所示;
require 'sinatra'
require 'slim'
get '/' do
slim :index
end
(3)新建layout.slim和index.slim两个文件,其中内容分别如下所示;
layout.slim
doctype html
html
head
meta charset="utf-8"
title Just Do It
link rel="stylesheet" media="screen, projection" href="/styles.css"
/[if lt IE 9]
script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"
body
h1 Just do It
== yield
index.slim
h2 myTask
ul.tasks
li Get Milk
(4)重新执行代码,打开浏览器,发现和之前的页面是没有变化的说明操作成功。如下图所示;
2.3.4 增加动态内容
(1)在之前main.rb文件内容最后面,增加新的代码,如下所示;
第一行,
/:task
的意思是从url中提取参数的值;
第二行,新建了实例变量@task
,通过params哈希实现的赋值,这个实例变量是可以在视图中使用的;
第三行,依旧使用slim模块打开新的视图task.slim;
get '/:task' do
@task = params[:task]
slim :task
end
(2)新建task.slim文件
打开文本编辑器输入如下所示的内容,然后放入sinatratest文件夹的views子文件夹里;
h2 My Tasks
= @task
(3)执行文件
重新运行服务,打开浏览器,输入http://localhost:4567/get-milk
,得到如下的结果,可以看到我们在task.slim视图中得到了get-mik的参数值;
(4)增加新的效果
修改之前main.rb文件中的@task
后面的内容,如下所示;
get '/:task' do
@task = params[:task].split('-').join(' ').capitalize
slim :task
end
重新执行代码,得到新的界面结果,发现-
没有了,G也是变成大写了;
2.3.5 表单
打开index.slim文件,将里面的内容替换为
form action="/" method="POST"
input type="text" name="task"
input.button type="submit" value="New Task >>"
同时更改main.rb文件,再后面加上如下代码:
post '/' do
@task = params[:task]
slim :task
end
重新运行代码,打开浏览器,输入网址http://localhost:4567
,得到如下的结果;
过程分析:第一步,首先输入网址http://localhost:4567后打开index.slim的视图,如下图所示;
第二步,接着在文本框里面输入123,如下图所示;
第三步,因为表单是采用POST方法提交的,所以会打开task.slim视图,如下图所示;
2.3.6 DataMapper和SQLite使用
(1)安装DataMapper和SQLite,使用命令
gem install data_mapper dm-sqlite-adapter sqlite3
安装成功,界面如下:
(2)新建DataMapper说明
此语句是告知DataMapper,我们将使用SQLite数据库,输入如下所示的代码,并将其放到main.rb的前面;
DataMapper.setup(:default, ENV['DATABASE_URL'] || "sqlite3://#{Dir.pwd}/development.db")
(3)创建Task类
打开main.rb文件,首先在文件首部处加入引用
require 'data_mapper'
然后,再文件的最后加入如下代码:
class Task
include DataMapper::Resource
property :id, Serial
property :name, String, :required => true
property :completed_at, DateTime
end
DataMapper.finalize
(4)增加Tasks到数据库
通过irb
创建新的Task,
第一步,打开终端,进入sinatratest所在的根目录,然后输入如下的命令:
irb
第二步,接着输入需要的引用的模块,命令require './main'
,如下所示
第三步, 创建Tasks table,输入如下的命令;
Task.auto_migrate!
第四步,增加tasks,命令如下所示;
Task.create(name: "get the milk")
Task.create(name: "order books")
Task.create(name: "pick up dry cleaning")
Task.create(name: "phone plumber")
发现APP根目录处增加了一个新的文件development.db
,至此Tasks已经保存到数据库中去了,如下图所示;
(4)加载显示Tasks
第一步,修改main.rb文件内容,加上如下代码;
Task.all
将会读取数据库中所有的tasks,然后将其传给实例变量@tasks
get '/' do
@tasks = Task.all
slim :index
end
最后整个main.rb文件如下所示;
require 'sinatra'
require 'slim'
require 'data_mapper'
DataMapper.setup(:default, ENV['DATABASE_URL'] || "sqlite3://#{Dir.pwd}/development.db")
class Task
include DataMapper::Resource
property :id, Serial
property :name, String, :required => true
property :completed_at, DateTime
end
DataMapper.finalize
get '/' do
@tasks = Task.all
slim :index
end
第二步,修改index.slim的内容,在最后一行处加入如下代码;
form action="/" method="POST"
input type="text" name="task[name]"
input.button type="submit" value="New Task >>"
h2 My Tasks
ul.tasks
- @tasks.each do |task|
li.task= task.name
第三步,重新执行代码,打开浏览器,输入网址http://localhost:4567/
,打开的界面如下所示,我们可以看到已经读取了数据库中的Tasks;
2.3.7 表单内容写入数据库
第一步,在之前的main.rb文件的最后加入处理表单的代码,如下所示:
首先是读取表单中的参数值,然后通过params哈希赋值给
Task.create
,最后在重定向,使得可以在页面刷新新增的Task结果;
post '/' do
Task.create params[:task]
redirect to('/')
end
第二步,重新加载,刷新浏览器,在表单文本框中输入内容my new task
,提交后显示新的Tasks列表,如下如所示;
2.3.8 删除Task
(1)修改task.slim
的文件,替换为如下所示的内容;
li.task id=task.id
= task.name
form.delete action="/task/#{task.id}" method="POST"
input type="hidden" name="_method" value="DELETE"
input type="submit" value="×" title="Delete Task"
(2)修改index.slim
文件,其他不变,将最后的代码块替换为如下的格式
ul.tasks
- @tasks.each do |task|
== slim :task, locals: { task: task }
(3)修改main.rb
文件,在最后加入删除操作,如下代码所示;
delete '/task/:id' do
Task.get(params[:id]).destroy
redirect to('/')
end
(4)重新启动服务,打开浏览器,输入网址http://localhost:4567/
得到的结果如下所示;
点击按钮,即可以删除相应的task,这里我们点击删除my new task
,得到如下结果;
2.3.9 Task完成情况
(1)更改task.slim内容
通过设置task的
completed_at
属性完成,如果completed_at
的值是nil
的,则说明task没有完成,否则记录时间,算作completed_at
的值,即为task完成时间;
li.task
= task.name
form.update action="/task/#{task.id}" method="POST"
input type="hidden" name="_method" value="PUT"
-if task.completed_at.nil?
input type="submit" value=" " title="Complete Task"
-else
input type="submit" value="✓" title="Uncomplete Task"
form.delete action="/task/#{task.id}" method="POST"
input type="hidden" name="_method" value="DELETE"
input type="submit" value="×" title="Delete Task"
(2)修改main.rb文件内容,替换之前的删除模块,代码如下所示;
put '/task/:id' do
task = Task.get params[:id]
task.completed_at = task.completed_at.nil? ? Time.now : nil
task.save
redirect to('/')
end
(3)重新开启服务,打开浏览器,输入网址http://localhost:4567
,执行结果如下图所示;
可以根据task有没有完成,要是完成了可在task中选择打对号,如下图所示;
2.4 增加样式和Tasks列表
2.4.1 增加一些样式
(1)修改layout.slim
文件中的内容,在首行增加如下所示的代码:
link rel="stylesheet" media="screen, projection" href="/styles.css"
(2)新建styles.css
文件,写入如下代码,并将styles.css
文件放入public文件夹里面;
.completed{
text-decoration: line-through;
}
.tasks{
padding:0;
list-style:none;
width:400px;
}
.task{
position:relative;
padding:2px 0 2px 28px;
border-bottom: dotted 1px #ccc;
}
form.update{
position:absolute;
bottom:2px;
left:0;
}
form.update input{
background:white;
color:white;
padding:0 2px;
border:solid 1px gray;
cursor:pointer;
}
.tasks li.completed form.update input{
color:#47FD6B;
}
form.delete{
display:inline;
}
form.delete input{
background:none;
cursor:pointer;
border:none;
}
(3)重新加载服务,打开浏览器,输入网址http://localhost:4567/
,打开的界面如下所示;
2.4.2 更改Task的界面样式
(1)修改task.slim
的内容,如下图所示;
li.task id=task.id class=(task.completed_at.nil? ? "" : "completed")
= task.name
form.update action="/task/#{task.id}" method="POST"
input type="hidden" name="_method" value="PUT"
-if task.completed_at.nil?
input type="submit" value=" " title="Complete Task"
-else
input type="submit" value="✓" title="Uncomplete Task"
form.delete action="/task/#{task.id}" method="POST"
input type="hidden" name="_method" value="DELETE"
input type="submit" value="×" title="Delete Task"
(2)重新加载服务,打开浏览器,输入网址http://localhost:4567/
,打开的界面如下所示;
2.4.3 Tasks的列表们
(1)修改main.rb
的内容,如下所示;
Lists将包含很多的tasks,DataMapper通过associations表示lists和tasks之间的关系,这是通过task中的
belongs_to
和lists中的has n
进行声明的
class Task
include DataMapper::Resource
property :id, Serial
property :name, String, :required => true
property :completed_at, DateTime
belongs_to :list
end
class List
include DataMapper::Resource
property :id, Serial
property :name, String, :required => true
has n, :tasks, :constraint => :destroy
end
DataMapper.finalize
(2)更新当前数据库,命令如下所示;
irb
require './main'
DataMapper.auto_migrate!
通过以上命令,可以将数据库中存在的tasks全部删除;
2.4.4 增加lists
(1)修改main.rb
文件中的内容,在最后加上如下所示的代码:
post '/new/list' do
List.create params['list']
redirect to('/')
end
delete '/list/:id' do
List.get(params[:id]).destroy
redirect to('/')
end
(2)重新写index.slim
文件,内容如下所示
实例变量
@lists
代表了数据库中所有的lists
form.new action="/new/list" method="POST"
input type="text" name="list[name]"
input type="submit" value="+ List"
ul.lists
- @lists.each do |list|
== slim :list, locals: { list: list }
(3)修改main.rb
文件中的内容,将之前的代码(如下所示):
get '/' do
@tasks = Task.all
slim :index
end
更换为如下的代码:
get '/' do
@lists = List.all(:order => [:name])
slim :index
end
(4)创建list.slim
文件,用来展示每一个list的tasks,内容如下所示:
li.list
h2= list.name
form.new action="/#{list.id}" method="POST"
input type="text" name="task[name]"
ul.tasks
- list.tasks.each do |task|
== slim :task, locals: { task: task }
form.destroy action="/list/#{list.id}" method="POST"
input type="hidden" name="_method" value="DELETE"
input type="submit" value="×"
(5)重新加载服务,打开浏览器,输入网址http://localhost:4567/
,得到如下界面;
在文本框中依次输入list1
和list2
,添加完毕后效果如下图所示;
2.4.5 增加task到list中
(1)修改main.rb
文件内容,依此来处理增加操作,将如下代码:
post '/' do
Task.create params['task']
redirect to('/')
end
替换为如下的代码:
post '/:id' do
List.get(params[:id]).tasks.create params['task']
redirect to('/')
end
(2)重新加载服务,打开浏览器,输入网址http://localhost:4567/
,得到如下界面;
2.4.6 更多样式
(1)在style.css
文件中增加下面的代码:
.lists{
padding:0;
list-style:none;
overflow:hidden;
}
.list{
float: left;
width:23%;
margin:0 1%;
border-top:solid 5px #ccc;
}
(2)同时需要移除style.css
第8行中的width:400px;
(3)重新加载服务,打开浏览器,输入网址http://localhost:4567/
,得到如下界面;
2.4 使用Sass和部署发布
2.4.1 logo
(1)打开style.css
文件,增加如下所示的代码:
h1.logo{
font-family: helvetica,arial,sans-serif;
font-size: 24px;
color: white;
padding: 64px 0 0;
margin: 0 auto;
text-transform: uppercase;
text-align: center;
font-weight: normal;
letter-spacing: 0.3em;
background: transparent url(/public/logo.png) 50% 0 no-repeat;
}
(2)将logo图片放入public文件夹里
(3)修改layout.slim
文件,如下所示
link rel="stylesheet" media="screen, projection" href="/styles.css"
doctype html
html
head
meta charset="utf-8"
title Just Do It!
link rel="shortcut icon" href="/favicon.ico"
link rel="stylesheet" media="screen, projection" href="/styles.css"
/[if lt IE 9]
script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"
body
h1.logo Just Do It!
== yield
(4)重新加载服务,打开浏览器,输入网址http://localhost:4567/
,得到如下界面;
2.4.2 得到Sassy
Sass (Syntactically Awesome Stylesheets),是CSS的模版语言,就是可以在服务器上编译生成CSS文件,目前有两个版本,一个是原生的SASS,另一个是SCSS(Sassy CSS),下面我们以SCSS应用为主。
(1)安装sass
gem install sass
安装成功,如下图所示;
(2)在main.rb
文件中增加sass处理模块,代码如下所示吧:
get '/styles.css' do
scss :styles
end
(3)在public文件夹下面,创建styles.scss
,并将styles.css
内容复制过去,然后删除styles.css
(4)
2.4.5 Heroku
Heroku是部署Sinatra apps的服务,它是完全免费的。Heroku平台的灵活性极高且支持多种编程语言。若想把程序部署到Heroku上,开发者要使用Git把程序推送到Heroku的Git服务器上。在服务器上,git push命令会自动触发安装、配置和部署程序。在使用之前需要准备的资料有Heroku账号、Mac上安装Git。
(1)安装Heroku,使用命令如下:
gem install heroku
安装不成功,出现错误的原因是,heroku must be installed from cli.heroku.com. This gem is no longer available.
(2)新的安装方法
第一步,打开终端输入如下命令
brew install heroku/brew/heroku
安装依然没有成功,出现了如下的错误:
(3)进一步新的方法
第一步,使用nmp的方式进行安装,需要先安装node,安装命令如下:
brew install node
node安装成功,并且npm的版本是6.4.1,如下图所示
第二步,安装heroku,命令如下所示:
npm install -g heroku
第三步,通过命令heroku version
,检测安装成功没有,如下图所示,发现安装的heroku版本是7.18.9;
(4)登陆heroku,使用如下命令
heroku login
显示登陆成功,如下图所示;
(5)使用SSH建立连接,命令如下所示:
heroku keys:add
显示第一次的连接建立成功,如下图所示;
(6)创建app名称在Heroku上,输入命令如下:
heroku create sinatratest
成功创建应用名称sintratest2
,如下图所示;
参考网址:
https://devcenter.heroku.com/articles/heroku-cli#download-and-install
https://laravel-china.org/articles/2602/how-to-quickly-use-heroku-to-deploy-your-laravel-application
2.4.6 Bundler
Bundler是用来管理应用中各种依赖包的,包含了所有的gems以及gem本身的依赖包。通过Bundler可以自动下载安装对应版本的gems。
(1)安装Bundler,使用命令如下:
gem install bundler
(2)创建Gemfile文件,内容如下所示:
source :rubygems
gem "sinatra"
gem "datamapper"
gem "slim"
gem "sass"
gem "dm-postgres-adapter", :group => :production
gem "dm-sqlite-adapter", :group => :development
(3)创建Rackup文件,命名为config.ru
,内容如下所示:
其中数据库连接操作放到
config.ru
中了,则main.rb
文件需要删除DataMapper.setup(:default, ENV['DATABASE_URL'] || "sqlite3://#{Dir.pwd}/development.db")
这条语句。
require 'bundler'
Bundler.require
require './main'
DataMapper.setup(:default, ENV['DATABASE_URL'] || "sqlite3://#{Dir.pwd}/development.db")
run Sinatra::Application
(4)本地测试,使用如下语句:
bundle install --without production
会在根目录生成.bundle
隐藏文件,并同时生成Gemfile.lock
,里面包含了应用中所有用到的gem列表,如下图所示;
(5)设置Heroku不要使用development
组,语句如下所示:
heroku config:add BUNDLE_WITHOUT="development:test" --app sinatratest2
(6)部署前最后一道核查,确定项目在本地是否运行良好的,终端进入项目根目录,输入如下命令所示;
rackup
打开浏览器,输入网址http://localhost:9292/
,界面如下所示,应用没有问题,可以部署发布;
2.4.7 部署发布
(1)创建.gitignore
,放于根目录下,内容如下所示,这将阻止将development.db
和.bundle
文件上传到远程的仓库;
development.db
.bundle
(2)初始化Git,输入如下所示的命令:
git init
git add .
git commit -m 'initial deployment'
(3)部署发布应用,命令如下所示,但是没有部署成功;
git push heroku master
重新创建应用名,然后再部署,居然成功了,分别如下图所示;
(4)最后一步,更改数据库
heroku console
Ruby console for stark-falls-12775.heroku.com
>> DataMapper.auto_migrate!
(5)打开网站
打开终端,进入本地应用所在的路径,输入如下所示的命令:
heroku open
或者打开浏览器,手工输入网址https://stark-falls-12775.herokuapp.com
,也可以打开已经部署完毕的应用;
【备注】详细参考了以下的安装方法,
中文,https://www.cnblogs.com/daguo/p/4097263.html;
英文,https://www.sitepoint.com/rails-development-101-rvm/;