似乎在Sinatra中,所有路由处理程序都被写入一个文件中,如果我理解它是一个大/小控制器。有没有办法将它拆分成单独的独立文件,所以当让我们说某人调用“/”时 - 执行一个动作,如果接收到像“/ posts / 2”这样的smth,那么另一个动作 - 在PHP中应用的类似逻辑?
答案 0 :(得分:393)
这是我使用的Sinatra应用程序的基本模板。 (我的大型应用程序有200多个这样的文件,不计算供应商的宝石,覆盖75-100个显式路由。其中一些路由是Regexp路由,覆盖额外的50多个路由模式。)使用Thin时,运行一个像这样的app使用:
thin -R config.ru start
修改:我现在根据以下名为 Monk 维护自己的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 helpers/ init.rb partials.rb models/ init.rb user.rb routes/ init.rb login.rb main.rb views/ 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
答案 1 :(得分:10)
绝对。要查看此示例,我建议您下载Monk gem,如下所述:
https://github.com/monkrb/monk
您可以通过rubygems.org'gem install'。获得gem后,使用上面链接的说明生成示例应用程序。
请注意,除非您愿意(实际上我认为它可能不是最新版本),否则您不必使用Monk进行实际开发。关键是要了解如何在MVC样式中轻松构建应用程序(使用单独的类似控制器的路径文件)。
如果你看一下Monk如何处理它,这很简单,主要是需要在不同目录中的文件,例如(你必须定义root_path):
Dir[root_path("app/**/*.rb")].each do |file|
require file
end
答案 2 :(得分:10)
谷歌搜索“Sinatra样板文件”,以了解其他人如何布置他们的Sinatra应用程序。从那里你可以找到一个适合你的需求或只是自己做。做起来并不难。随着您开发更多Sinatra应用程序,您可以添加到样板文件中。
这是我为所有项目制作和使用的内容:
答案 3 :(得分:7)
我知道这是一个古老的查询,但我仍然无法相信没有人提到Padrino你可以将它作为Sinatra之上的框架使用,或者只是零碎地添加你感兴趣的宝石。它踢了十个屁股!
答案 4 :(得分:2)
我在同一网站上托管不同项目的方法是以这种方式使用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
...
我使用的子项目的另一个细节是将它们的名称,描述和路由添加到某种全局变量中,"/"
使用它来制作指南主页,但我没有一个片段现在。
答案 5 :(得分:1)
当Monk不为我工作时,我开始自己制作模板。
如果你仔细想想,捆绑一组文件没什么特别之处。我们在2011年初RedDotRubyConf期间向我解释了和尚哲学,他们特别告诉我,使用它是非常可选的,特别是现在它很难维护。
对于想要使用ActiveRecord的人来说,这是一个良好的开端:
Simple Sinatra MVC
答案 6 :(得分:1)
在这里阅读文档:
似乎Sinatra允许您将应用程序分解为Ruby模块,可以通过Sinatra“register”方法或“helpers”方法将其分解,如下所示:
require 'sinatra/base'
module Sinatra
module Sample
module Helpers
def require_logged_in()
redirect('/login') unless session[:authenticated]
end
end
end
end
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
#!/usr/bin/env ruby
require 'sinatra'
require_relative 'routing/foos'
class SampleApp < Sinatra::Base
helpers Sinatra::Sample::Helpers
register Sinatra::Sample::Routing::Foos
end
答案 7 :(得分:1)
Sinatra对大型项目的模块化关键是学习使用底层工具。
SitePoint有一个非常good tutorial,您可以在其中看到模块化的Sinatra应用程序和帮助程序。但是,您应该特别注意一个重要细节。您可以使用Rackup保留多个Sinatra应用程序并 mount 。一旦您知道如何编写基本应用程序,请查看该教程的 config.ru 文件,并观察它们如何安装独立的Sinatra应用程序。
一旦你学会了使用Rack运行Sinatra,就会开启一个全新的模块化战略世界。这显然邀请尝试一些非常有用的东西:现在你可以依靠为每个子应用程序拥有单独的Gems,这可以让你轻松地模拟你的模块。
不要低估为您的应用使用gem-modules的强大功能。您可以轻松地在分隔良好的环境中测试实验性更改并轻松部署它们。如果出现问题,同样容易还原。
有一千种组织代码的方法,因此尝试获得类似于Rails的布局并不会有什么坏处。但是,还有一些great posts关于如何自定义您自己的结构。该帖子涵盖了大多数Web开发人员的其他常见需求。
如果您有时间,我建议您了解有关Rack的更多信息,这是任何基于Ruby的Web应用程序的共同基础。它可能对你的工作方式产生的影响要小得多,但是大多数人总是会在他们的应用程序上做一些更适合作为Rack中间件的任务。