浏览 9069 次
精华帖 (1) :: 良好帖 (7) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2010-04-04
最后修改:2010-04-04
前些天有一个需求,需要写一个小程序来收集用户的Email,非常的简单: 1.一个用户输入Email的界面 2.提交Email表单后,提示用户已经记录了他/她的Email,然后跳转到首页. 这是一个简单得不能再简单的小功能了,但是由于这个功能是要求放在一个独立的服务器上的,跟现有的项目也毫不相干的,我并不想在现有的Rails项目中增加这个功能.我首先想到的是新建一个Rails项目实现这个功能,动手之前我又犹豫了,这么一个简单的东西,要如此大动干戈么? 为什么说是大动干戈呢?Rails是一个全能的Web框架,提供了许多方便快捷的功能,也正是因此而凌驾于基本Web开发框架之上,但是对于这么一个简单的需求,Rails超强的功能反而成了累赘,根本就用不着啊,杀鸡用牛刀就是形容这个的. 直观地说,就是我不想为了记录一下用户的Email,就要安装Rails gem,要建立数个毫无用处的文件夹,要上传数个不相干的文件,我就是想快速简单地解决这事. 于是我想起了前些日子才发布了1.0版本的Sinatra,在些之前我对Sinatra的了解就是知道很小(好像只有250KB),和看过一些示例的代码片段. 上面说了这么多,仅仅是为了点题:Sinatra:Rails的有益补充. 使用某种技术之前一定要先看官方的文档,再Google一下资料,这种有益的习惯我一直都有保持 安装: # 安装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 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) 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请求,匹配的url是这样的: http://www.yourdomain.com/ get '/' do erb :index #用erb渲染 views/index.erb 文件 # 注: Sinatra中默认的网页文件都是放在根目录下的views目录中,但是可以配置,我就不折腾了. end # 处理http://www.yourdomain.com/contact,注意了,是post方法哦 post '/contact' do #下面这两句是不是很熟悉啊:) email = Email.new :email => params[:email],:created_at => Time.now email.save erb :success end 咱们看看views: # views/index.erb <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head> <meta http-equiv="content-type" content="application/xhtml+xml; charset=UTF-8" /> <title>Wellcome to DiginDigin.com</title> </head> <body> <div style="text-align:center;margin:100px auto;"> <h2>Email</h2> <form action="/contact" method="post"> <input name="email" type="text" /> <input type="submit" value="Submit" /> </form> </div> </body> </html> # views/success.erb <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head> <meta http-equiv="content-type" content="application/xhtml+xml; charset=UTF-8" /> <title>Wellcome</title> <meta http-equiv="refresh" content="5;http://www.yourdomain.com" /> </head> <body> <div style="text-align:center;margin:100px auto;"> <h2>欢迎加入,敬请期待</h2> <p>5秒后,自动跳转到我们的首页</p> </div> </body> </html> 至此,这个程序已经算是完成了,可以这样启动应用程序: cd contacts ruby app.rb #默认启动的话,监听的是4567端口,可以在浏览器输入 http://localhost: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' # 在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; } } } 这个Sinatra的小程序相当简单,也没什么技术含量,但是它确实解决了我的问题,简单而优雅. 我觉得Sinatra提供了一个Web框架的最基本的东西,可以非常快速地解决一些小需求,我并没做做压力测试之类的,但是我相信Sinatra的速度肯定是比Rails快的,只要看看Rails堆栈里那一堆的Rack中间件,你就明白我为什么这样说了.当然Rails从来都不是速度取胜的 我也不觉得Sinatra可以和Rails争一日之长短,它提供的功能太简单,开发稍微复杂的项目,肯定是要自己写很多东西的,而这些Rails早已经为你准备好了.但是当你有一些小需求(比如像我上面写的这种),Sinatra就非常适合了. 快速而小巧,还有比这更能俘虏懒惰程序员的心么? 我不愿意用"简单"这个词来形容Sinatra,我更加愿意用"简洁"来形容它. Sinatra:一个可以作为Rails的有益补充的框架. 简洁而不简单! 参考: 官方网站: http://www.sinatrarb.com/ The Sinatra Book: http://sinatra-book.gittr.com/ 一些在Nginx + Passenger下部署Sinatra的链接: http://stackoverflow.com/questions/2321314/multiple-rack-apps-on-nginx-passenger-one-as-root-the-other-not-config-help http://tommy.chheng.com/index.php/2009/06/deploying-a-sinatra-app-on-nginx-passenger-with-capistrano-and-git/ 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2010-04-05
最后修改:2010-04-05
既然是这么简单的事情,用rack写也比较有趣:
一共5个文件,views里面和搂主的一样: hooopo@x-hooopo:~/contact$ ls app.rb config.yml console views app.rb #!/usr/bin/env ruby require "rubygems" require "rack" require "yaml" require "logger" require 'active_record' config = YAML::load(File.open(File.dirname(__FILE__) + "/config.yml")) ActiveRecord::Base.establish_connection(config) class Email < ActiveRecord::Base validates_presence_of :email validates_format_of :email,:with => /\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/i end def process_request(env) request = Rack::Request.new(env) if request.post? Email.create! :email => request.params["email"] rescue return "Email Format Error!" File.read("views/success.html") else "invalide request!" end end builder = Rack::Builder.new do use Rack::CommonLogger, Logger.new("/var/log/rack.log") use Rack::ContentType, "text/html" use Rack::ContentLength map "/" do run lambda{|env| [200, {}, File.read("views/index.html")]} end map "/contact" do run lambda{|env| [200, {}, process_request(env)]} end end Rack::Handler::Mongrel.run builder, :Port => 8080 config.yml adapter: mysql encode: utf8 host: localhost username: root password: ****** database: contacts 运行: sudo chmod +x ./* ./app.rb 模仿rails写了一个简单的console: console #!/usr/bin/env ruby require 'rubygems' require 'yaml' require 'active_record' require 'irb' require 'irb/completion' config = YAML::load(File.open(File.dirname(__FILE__) + "/config.yml")) ActiveRecord::Base.establish_connection(config) class Email < ActiveRecord::Base end IRB.start 运行console: hooopo@x-hooopo:~/contact$ ./console Irbrc Loading... >> enable_hirb => true >> Email.all +----+-------------------+--------------------------------+ | id | email | created_at | +----+-------------------+--------------------------------+ | 1 | hoooopo@gmail.com | Sun Apr 04 22:44:46 +0800 2010 | | 2 | hooopo@gmail.com | Sun Apr 04 22:58:56 +0800 2010 | +----+-------------------+--------------------------------+ 2 rows in set >> |
|
返回顶楼 | |
发表时间:2010-04-05
为啥要把虎跑加进去啊....
|
|
返回顶楼 | |
发表时间:2010-07-08
@Hooopo 说起来我还真没有写过Rack的程序呢,之前看过很多Rack的资料,对Rack的原理一知半解,可是你让我写一个Rack,一时之间还真不知道如何下手。
你的Rack程序比我用Sinatra要简洁得多 |
|
返回顶楼 | |
发表时间:2010-07-22
yangzhihuan 写道 @Hooopo 说起来我还真没有写过Rack的程序呢,之前看过很多Rack的资料,对Rack的原理一知半解,可是你让我写一个Rack,一时之间还真不知道如何下手。
你的Rack程序比我用Sinatra要简洁得多 http://www.iteye.com/topic/605707 |
|
返回顶楼 | |