通过多个文件将Sinatra用于较大的项目

在Sinatra看来,所有的路由处理程序都被写入一个文件中,如果我理解的话,它就是一个大/小的控制器。 有什么办法把它分成独立的文件,所以当我们说有人调用“/” – 一个动作被执行,如果smth像“/ posts / 2”被接收,那么另一个动作 – 在PHP中应用类似的逻辑?

这里是我使用的Sinatra应用程序的基本模板。 (我的大型应用程序有200多个这样的文件,不包括供应商的gem,涵盖75-100显式路线,其中一些路线是正则expression式路线,覆盖额外的50多种路线模式)。使用Thin时,运行这样的应用程序使用:
thin -R config.ru start

编辑 :我现在正在维护我自己的和尚骨架根据下面叫Riblits 。 要使用它来复制我的模板作为您自己的项目的基础:

 # Before creating your project monk add riblits git://github.com/Phrogz/riblits.git # Inside your empty project directory monk init -s riblits 

文件格式:

 config.ru
 app.rb
助手/
   init.rb
   partials.rb
楷模/
   init.rb
   user.rb
路线/
   init.rb
   login.rb
   main.rb的
意见/
   layout.haml
   login.haml
   main.haml

config.ru

 root = ::File.dirname(__FILE__) require ::File.join( root, 'app' ) run MyApp.new 

app.rb

 # encoding: utf-8 require 'sinatra' require 'haml' class MyApp < Sinatra::Application enable :sessions configure :production do set :haml, { :ugly=>true } set :clean_trace, true end configure :development do # ... end helpers do include Rack::Utils alias_method :h, :escape_html end end require_relative 'models/init' require_relative 'helpers/init' require_relative 'routes/init' 

助手/ init.rb

 # encoding: utf-8 require_relative 'partials' MyApp.helpers PartialPartials require_relative 'nicebytes' MyApp.helpers NiceBytes 

助手/ partials.rb

 # encoding: utf-8 module PartialPartials def spoof_request(uri,env_modifications={}) call(env.merge("PATH_INFO" => uri).merge(env_modifications)).last.join end def partial( page, variables={} ) haml page, {layout:false}, variables end end 

助手/ nicebytes.rb

 # encoding: utf-8 module NiceBytes K = 2.0**10 M = 2.0**20 G = 2.0**30 T = 2.0**40 def nice_bytes( bytes, max_digits=3 ) value, suffix, precision = case bytes when 0...K [ bytes, 'B', 0 ] else value, suffix = case bytes when K...M then [ bytes / K, 'kiB' ] when M...G then [ bytes / M, 'MiB' ] when G...T then [ bytes / G, 'GiB' ] else [ bytes / T, 'TiB' ] end used_digits = case value when 0...10 then 1 when 10...100 then 2 when 100...1000 then 3 else 4 end leftover_digits = max_digits - used_digits [ value, suffix, leftover_digits > 0 ? leftover_digits : 0 ] end "%.#{precision}f#{suffix}" % value end module_function :nice_bytes # Allow NiceBytes.nice_bytes outside of Sinatra end 

车型/ init.rb

 # encoding: utf-8 require 'sequel' DB = Sequel.postgres 'dbname', user:'bduser', password:'dbpass', host:'localhost' DB << "SET CLIENT_ENCODING TO 'UTF8';" require_relative 'users' 

车型/ user.rb

 # encoding: utf-8 class User < Sequel::Model # ... end 

路线/ init.rb

 # encoding: utf-8 require_relative 'login' require_relative 'main' 

路线/ login.rb

 # encoding: utf-8 class MyApp < Sinatra::Application get "/login" do @title = "Login" haml :login end post "/login" do # Define your own check_login if user = check_login session[ :user ] = user.pk redirect '/' else redirect '/login' end end get "/logout" do session[:user] = session[:pass] = nil redirect '/' end end 

路线/ main.rb的

 # encoding: utf-8 class MyApp < Sinatra::Application get "/" do @title = "Welcome to MyApp" haml :main end end 

意见/ layout.haml

 !!! XML !!! 1.1 %html(xmlns="http://www.w3.org/1999/xhtml") %head %title= @title %link(rel="icon" type="image/png" href="/favicon.png") %meta(http-equiv="X-UA-Compatible" content="IE=8") %meta(http-equiv="Content-Script-Type" content="text/javascript" ) %meta(http-equiv="Content-Style-Type" content="text/css" ) %meta(http-equiv="Content-Type" content="text/html; charset=utf-8" ) %meta(http-equiv="expires" content="0" ) %meta(name="author" content="MeWho") %body{id:@action} %h1= @title #content= yield 

绝对。 要看到这个例子,我build议下载这里描述的僧侣gem:

https://github.com/monkrb/monk

你可以通过rubygems.org“gem install”。 一旦你有了gem,使用上面链接的说明生成一个示例应用程序。

请注意,除非您想(实际上我认为它可能不是最新的),否则您不必使用Monk进行实际开发。 重点在于如果你愿意的话,你可以很容易地用MVC风格构build你的应用程序(带有独立的控制器类path文件)。

如果你看看Monk如何处理它,这很简单,主要是需要在不同目录中的文件,像(你必须定义root_path):

 Dir[root_path("app/**/*.rb")].each do |file| require file end 

做一个谷歌search“Sinatra样板”,以了解其他人如何布置他们的Sinatra应用程序的一些想法。 从那里你可以find一个适合你的需求,或者只是自己做。 这并不难。 当你开发更多的Sinatra应用程序,你可以添加到你的样板。

以下是我为我的所有项目制作和使用的内容:

https://github.com/rziehl/sinatra-boilerplate

我知道这是一个古老的查询,但我仍然不能相信没有人提到Padrino你可以用它作为Sinatra之上的框架,或者零星地添加你感兴趣的gem。 它踢十屁股buttloads!

对于大型项目Sinatra模块化的关键是学习使用底层工具。

SitePoint有一个非常好的教程 ,您可以从中看到模块化的Sinatra应用程序和帮助程序。 但是你应该特别注意一个重要的细节。 您保留多个Sinatra应用程序并使用Rackup 安装它们。 一旦你知道如何编写一个基本的应用程序看看该教程的config.ru文件,并观察他们如何安装独立的Sinatra应用程序。

一旦你学会了用Rack运行Sinatra,模块化策略的全新世界将会打开。 这显然是要尝试一些真正有用的东西:现在,您可以依靠每个子应用程序拥有单独的Gem,可以使您轻松地对模块进行版本化。

不要低估为您的应用程序使用gem模块的能力。 您可以轻松地在一个分隔良好的环境中testing实验更改并轻松部署它们。 如果出现问题,同样容易恢复。

有上千种方法来组织你的代码,所以它不会损害试图获得类似于Rails的布局。 不过也有一些关于如何定制你自己的结构的伟大的职位 。 这篇文章涵盖了大多数Web开发人员的其他频繁需求

如果您有时间,我鼓励您更多地了解Rack,这是任何基于Ruby的Web应用程序的共同点。 它可能对你的工作产生的影响要小得多,但总是有一些大多数人在他们的应用程序上执行的任务更适合作为Rack中间件。

我在同一个网站上托pipe不同项目的方法是以这种方式使用sinatra/namespace

server.rb

 require "sinatra" require "sinatra/namespace" if [ENV["LOGNAME"], ENV["USER"]] == [nil, "naki"] require "sinatra/reloader" register Sinatra::Reloader set :port, 8719 else set :environment, :production end for server in Dir.glob "server_*.rb" require_relative server end get "/" do "this route is useless" end 

server_someproject.rb

 module SomeProject def self.foo bar ... end ... end namespace "/someproject" do set :views, settings.root get "" do redirect request.env["REQUEST_PATH"] + "/" end get "/" do haml :view_someproject end post "/foo" do ... SomeProject.foo ... end end 

view_someproject.haml

 !!! %html ... 

关于我使用的子项目的另一个细节是将它们的名称,描述和路由添加到某个全局variables中, "/"来创build指导主页,但是现在我没有一个片段。

在这里阅读文档:

Sinatra扩展

看来,Sinatra允许你将你的应用程序分解成Ruby模块,可以通过Sinatra“注册”方法或“helpers”方法来引入,如下所示:

helpers.rb

 require 'sinatra/base' module Sinatra module Sample module Helpers def require_logged_in() redirect('/login') unless session[:authenticated] end end end end 

路由/ foos.rb

 require 'sinatra/base' module Sinatra module Sample module Routing module Foos def self.registered(app) app.get '/foos/:id' do # invoke a helper require_logged_in # load a foo, or whatever erb :foos_view, :locals => { :foo => some_loaded_foo } end end end end end end 

app.rb

 #!/usr/bin/env ruby require 'sinatra' require_relative 'routing/foos' class SampleApp < Sinatra::Base helpers Sinatra::Sample::Helpers register Sinatra::Sample::Routing::Foos end 

当Monk不为我工作时,我开始自己开发模板。

如果你仔细想想,绑定一组文件没有什么特别之处。 2011年初在RedDotRubyConf期间向我解释了修士的哲学,他们特意告诉我,使用它真的是可选的,特别是现在它几乎不被维护。

对于那些想要使用ActiveRecord的人来说,这是一个很好的开始:

简单的Sinatra MVC

https://github.com/katgironpe/simple-sinatra-mvc