Chinaunix首页 | 论坛 | 博客
  • 博客访问: 853088
  • 博文数量: 188
  • 博客积分: 4433
  • 博客等级: 上校
  • 技术积分: 1905
  • 用 户 组: 普通用户
  • 注册时间: 2008-11-14 07:14
个人简介

linux

文章分类

全部博文(188)

文章存档

2016年(6)

2015年(22)

2014年(18)

2013年(5)

2012年(125)

2011年(10)

2010年(2)

分类: Python/Ruby

2012-02-28 11:33:02

一个基于Sinatra的小程序

前些天有一个需求,需要写一个小程序来收集用户的Email,非常的简单:
1.一个用户输入Email的界面
2.提交Email表单后,提示用户已经记录了他/她的Email,然后跳转到首页.

这是一个简单得不能再简单的小功能了,但是由于这个功能是要求放在一个独立的服务器上的,跟现有的项目也毫不相干的,我并不想在现有的Rails项目中增加这个功能.我首先想到的是新建一个Rails项目实现这个功能,动手之前我又犹豫了,这么一个简单的东西,要如此大动干戈么?

为什么说是大动干戈呢?Rails是一个全能的Web框架,提供了许多方便快捷的功能,也正是因此而凌驾于基本Web开发框架之上,但是对于这么一个简单的需求,Rails超强的功能反而成了累赘,根本就用不着啊,杀鸡用牛刀就是形容这个的.

直观地说,就是我不想为了记录一下用户的Email,就要安装Rails gem,要建立数个毫无用处的文件夹,要上传数个不相干的文件,我就是想快速简单地解决这事.

于是我想起了前些日子才发布了1.0版本的Sinatra,在些之前我对Sinatra的了解就是知道很小(好像只有250KB),和看过一些示例的代码片段.

上面说了这么多,仅仅是为了点题:Sinatra:Rails的有益补充.

使用某种技术之前一定要先看官方的文档,再Google一下资料,这种有益的习惯我一直都有保持

安装:
Ruby代码 复制代码 收藏代码
  1. # 安装Sinatra   
  2. gem install sinatra   
  3. #安装Rails的ActiveRecord,因为用Ruby操作数据库,除了直接写Sql外,我就会ActiveRecord,bty:我已经不在代码中直接写sql很多年了.   
  4. 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小程序的代码结构:
Ruby代码 复制代码 收藏代码
  1. |-contacts   
  2.   |-views   
  3.     |-index.erb   
  4.     |-success.erb   
  5.   |-app.rb   
  6.   |-config.ru   
  7.   |-email.rb  
|-contacts |-views |-index.erb |-success.erb |-app.rb |-config.ru |-email.rb

email.rb是一个ActiveRecord对象,跟在Rails中一样是个普通人,跟Sinatra半毛钱的关系都没有.

emails表的建表sql:
Ruby代码 复制代码 收藏代码
  1. 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)

Ruby代码 复制代码 收藏代码
  1. require 'rubygems' #这一句必不可少,如果你用的是Ruby 1.9.x,可以把这句删掉   
  2. gem 'activerecord','2.3.5'  
  3. require 'activerecord'  
  4.   
  5. # 在这里为了方便,我直接把数据库的连接设置写在里面了.   
  6. ActiveRecord::Base.establish_connection(   
  7.     :adapter  => "mysql",   
  8.     :encode => 'utf8',   
  9.     :host     => "localhost",   
  10.     :username => "root",   
  11.     :password => "12345678",   
  12.     :database => "contacts"  
  13. )   
  14.   
  15. class Email < ActiveRecord::Base   
  16.     validates_presence_of :email  
  17.     validates_format_of :email,:with => /\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/i   
  18. 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的示例代码简直就是一模一样的.
Ruby代码 复制代码 收藏代码
  1. require 'rubygems'  
  2. require 'sinatra'  
  3.   
  4. require File.join(File.dirname(__FILE__),'email')   
  5.   
  6. #处理get请求,匹配的url是这样的:    
  7. get '/' do  
  8.     erb :index #用erb渲染 views/index.erb 文件   
  9.     # 注: Sinatra中默认的网页文件都是放在根目录下的views目录中,但是可以配置,我就不折腾了.   
  10. end  
  11.   
  12. # 处理contact,注意了,是post方法哦   
  13. post '/contact' do  
  14.     #下面这两句是不是很熟悉啊:)   
  15.     email = Email.new :email => params[:email],:created_at => Time.now   
  16.     email.save   
  17.   
  18.     erb :success  
  19. 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:
Ruby代码 复制代码 收藏代码
  1. # views/index.erb   
  2. "-//W3C//DTD XHTML 1.0 Strict//EN" "">   
  3.   
  4. "" xml:lang="en" lang="en">   
  5.   
  6.      
  7.   
  8.     "content-type" content="application/xhtml+xml; charset=UTF-8" />   
  9.     Wellcome to DiginDigin.com   
  10.      
  11.      
  12.     "text-align:center;margin:100px auto;">   
  13.       

    Email

      
  14.       "/contact" method="post">   
  15.         "email" type="text" />   
  16.         "submit" value="Submit" />   
  17.          
  18.     
  
  •      
  •   
  •   
  • # views/success.erb   
  • "-//W3C//DTD XHTML 1.0 Strict//EN" "">   
  •   
  • "" xml:lang="en" lang="en">   
  •   
  •      
  •   
  •     "content-type" content="application/xhtml+xml; charset=UTF-8" />   
  •     Wellcome   
  •     "refresh" content="5;" />   
  •      
  •      
  •     "text-align:center;margin:100px auto;">   
  •       

    欢迎加入,敬请期待

      
  •       

    5秒后,自动跳转到我们的首页

      
  •     
  •   
  •      
  •   
  • # views/index.erb Wellcome to DiginDigin.com

    Email

    # views/success.erb Wellcome

    欢迎加入,敬请期待

    5秒后,自动跳转到我们的首页



    至此,这个程序已经算是完成了,可以这样启动应用程序:
    Ruby代码 复制代码 收藏代码
    1. cd contacts   
    2. ruby app.rb #默认启动的话,监听的是4567端口,可以在浏览器输入 访问   
    3.   
    4. #也可以用 p 选项指定端口   
    5. 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.
    Ruby代码 复制代码 收藏代码
    1. require 'rubygems'  
    2. require 'sinatra'  
    3.   
    4. set :env,:production  
    5. disable :run  
    6.   
    7. require 'app'  
    8.   
    9. # 在Sinatra的示例文档中是这样的: run Sinatra.application,但这样会报错的,修改后如下,正确启动.   
    10. run Sinatra::Application  
    require 'rubygems' require 'sinatra' set :env,:production disable :run require 'app' # 在Sinatra的示例文档中是这样的: run Sinatra.application,但这样会报错的,修改后如下,正确启动. run Sinatra::Application

    贴上我在 nginx.conf 中的配置:
    Ruby代码 复制代码 收藏代码
    1.   
    2. http {   
    3.     passenger_root /usr/local/ruby-enterprise-1.8.7/lib/ruby/gems/1.8/gems/passenger-2.2.3;   
    4.     passenger_ruby /usr/local/ruby-enterprise-1.8.7/bin/ruby;   
    5.   
    6.     server {   
    7.         listen       80;   
    8.         server_name  localhost;   
    9.     passenger_enabled on;   
    10.   
    11.         location / {   
    12.             root   /dev/contacts;   
    13.         }   
    14.   
    15.     }   
    16. }  
    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的链接:


    阅读(4457) | 评论(0) | 转发(0) |
    0

    上一篇:sqllit3 教学

    下一篇:安装 passenger/nginx

    给主人留下些什么吧!~~