一个基于Sinatra的小程序
前些天有一个需求,需要写一个小程序来收集用户的Email,非常的简单:
1.一个用户输入Email的界面
2.提交Email表单后,提示用户已经记录了他/她的Email,然后跳转到首页.
这是一个简单得不能再简单的小功能了,但是由于这个功能是要求放在一个独立的服务器上的,跟现有的项目也毫不相干的,我并不想在现有的Rails项目中增加这个功能.我首先想到的是新建一个Rails项目实现这个功能,动手之前我又犹豫了,这么一个简单的东西,要如此大动干戈么?
为什么说是大动干戈呢?Rails是一个全能的Web框架,提供了许多方便快捷的功能,也正是因此而凌驾于基本Web开发框架之上,但是对于这么一个简单的需求,Rails超强的功能反而成了累赘,根本就用不着啊,杀鸡用牛刀就是形容这个的.
直观地说,就是我不想为了记录一下用户的Email,就要安装Rails gem,要建立数个毫无用处的文件夹,要上传数个不相干的文件,我就是想快速简单地解决这事.
于是我想起了前些日子才发布了1.0版本的Sinatra,在些之前我对Sinatra的了解就是知道很小(好像只有250KB),和看过一些示例的代码片段.
上面说了这么多,仅仅是为了点题:Sinatra:Rails的有益补充.
使用某种技术之前一定要先看官方的文档,再Google一下资料,这种有益的习惯我一直都有保持
安装:
-
- gem install sinatra
-
- gem install activerecord v=2.3.5
# 安装Sinatra
gem install sinatra
#安装Rails的ActiveRecord,因为用Ruby操作数据库,除了直接写Sql外,我就会ActiveRecord,bty:我已经不在代码中直接写sql很多年了.
gem install activerecord v=2.3.5
以下是这个叫做contacts小程序的代码结构:
- |-contacts
- |-views
- |-index.erb
- |-success.erb
- |-app.rb
- |-config.ru
- |-email.rb
|-contacts
|-views
|-index.erb
|-success.erb
|-app.rb
|-config.ru
|-email.rb
email.rb是一个ActiveRecord对象,跟在Rails中一样是个普通人,跟Sinatra半毛钱的关系都没有.
emails表的建表sql:
- create table emails (id int(11) primary key AUTO_INCREMENT,email varchar(255) not null,created_at datetime)
create table emails (id int(11) primary key AUTO_INCREMENT,email varchar(255) not null,created_at datetime)
- require 'rubygems'
- gem 'activerecord','2.3.5'
- require 'activerecord'
-
-
- ActiveRecord::Base.establish_connection(
- :adapter => "mysql",
- :encode => 'utf8',
- :host => "localhost",
- :username => "root",
- :password => "12345678",
- :database => "contacts"
- )
-
- class Email < ActiveRecord::Base
- validates_presence_of :email
- validates_format_of :email,:with => /\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/i
- end
require 'rubygems' #这一句必不可少,如果你用的是Ruby 1.9.x,可以把这句删掉
gem 'activerecord','2.3.5'
require 'activerecord'
# 在这里为了方便,我直接把数据库的连接设置写在里面了.
ActiveRecord::Base.establish_connection(
:adapter => "mysql",
:encode => 'utf8',
:host => "localhost",
:username => "root",
:password => "12345678",
:database => "contacts"
)
class Email < ActiveRecord::Base
validates_presence_of :email
validates_format_of :email,:with => /\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/i
end
跟Sinatra有关系的是app.rb,这也是程序的主文件了(没错,就这么一个,当然是因为功能太简单的,但是如果太复杂的话,我直接用Rails去了)
app.rb的代码跟你看到的Singtra的示例代码简直就是一模一样的.
- require 'rubygems'
- require 'sinatra'
-
- require File.join(File.dirname(__FILE__),'email')
-
-
- get '/' do
- erb :index
-
- end
-
-
- post '/contact' do
-
- email = Email.new :email => params[:email],:created_at => Time.now
- email.save
-
- erb :success
- end
require 'rubygems'
require 'sinatra'
require File.join(File.dirname(__FILE__),'email')
#处理get请求,匹配的url是这样的:
get '/' do
erb :index #用erb渲染 views/index.erb 文件
# 注: Sinatra中默认的网页文件都是放在根目录下的views目录中,但是可以配置,我就不折腾了.
end
# 处理contact,注意了,是post方法哦
post '/contact' do
#下面这两句是不是很熟悉啊:)
email = Email.new :email => params[:email],:created_at => Time.now
email.save
erb :success
end
咱们看看views:
# views/index.erb
Wellcome to DiginDigin.com
Email
# views/success.erb
Wellcome
至此,这个程序已经算是完成了,可以这样启动应用程序:
- cd contacts
- ruby app.rb
-
-
- ruby app.rb -p 8000
cd contacts
ruby app.rb #默认启动的话,监听的是4567端口,可以在浏览器输入 访问
#也可以用 p 选项指定端口
ruby app.rb -p 8000
细心的同学会发现上面的代码结构中还有一个 config.ru 文件,看到.ru后缀就知道是 Rack 来袭了.没错, config.ru 是用来配置在支持Rack接口的服务器中运行这个小程序的,我用的是 Nginx + Passenger.
- require 'rubygems'
- require 'sinatra'
-
- set :env,:production
- disable :run
-
- require 'app'
-
-
- run Sinatra::Application
require 'rubygems'
require 'sinatra'
set :env,:production
disable :run
require 'app'
# 在Sinatra的示例文档中是这样的: run Sinatra.application,但这样会报错的,修改后如下,正确启动.
run Sinatra::Application
贴上我在 nginx.conf 中的配置:
-
- http {
- passenger_root /usr/local/ruby-enterprise-1.8.7/lib/ruby/gems/1.8/gems/passenger-2.2.3;
- passenger_ruby /usr/local/ruby-enterprise-1.8.7/bin/ruby;
-
- server {
- listen 80;
- server_name localhost;
- passenger_enabled on;
-
- location / {
- root /dev/contacts;
- }
-
- }
- }
http {
passenger_root /usr/local/ruby-enterprise-1.8.7/lib/ruby/gems/1.8/gems/passenger-2.2.3;
passenger_ruby /usr/local/ruby-enterprise-1.8.7/bin/ruby;
server {
listen 80;
server_name localhost;
passenger_enabled on;
location / {
root /dev/contacts;
}
}
}
这个Sinatra的小程序相当简单,也没什么技术含量,但是它确实解决了我的问题,简单而优雅.
我觉得Sinatra提供了一个Web框架的最基本的东西,可以非常快速地解决一些小需求,我并没做做压力测试之类的,但是我相信Sinatra的速度肯定是比Rails快的,只要看看Rails堆栈里那一堆的Rack中间件,你就明白我为什么这样说了.当然Rails从来都不是速度取胜的
我也不觉得Sinatra可以和Rails争一日之长短,它提供的功能太简单,开发稍微复杂的项目,肯定是要自己写很多东西的,而这些Rails早已经为你准备好了.但是当你有一些小需求(比如像我上面写的这种),Sinatra就非常适合了.
快速而小巧,还有比这更能俘虏懒惰程序员的心么?
我不愿意用"简单"这个词来形容Sinatra,我更加愿意用"简洁"来形容它.
Sinatra:一个可以作为Rails的有益补充的框架.
简洁而不简单!
参考:
官方网站:
The Sinatra Book:
一些在Nginx + Passenger下部署Sinatra的链接: