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

spa*_*key 182 ruby sinatra

似乎在Sinatra中所有路由处理程序都被写入一个文件中,如果我理解它是一个大/小控制器.有没有办法将它拆分成单独的独立文件,所以当让我们说某人调用"/"时 - 执行一个动作,如果接收到像"/ posts/2"这样的smth,那么另一个动作 - 在PHP中应用的类似逻辑?

Phr*_*ogz 394

这是我使用的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
Run Code Online (Sandbox Code Playgroud)

文件布局:

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
Run Code Online (Sandbox Code Playgroud)

 
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'
Run Code Online (Sandbox Code Playgroud)

 
助手/ init.rb

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

require_relative 'nicebytes'
MyApp.helpers NiceBytes
Run Code Online (Sandbox Code Playgroud)

 
助手/ 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
Run Code Online (Sandbox Code Playgroud)

 
助手/ 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
Run Code Online (Sandbox Code Playgroud)

 
车型/ 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'
Run Code Online (Sandbox Code Playgroud)

 
车型/ user.rb

# encoding: utf-8
class User < Sequel::Model
  # ...
end
Run Code Online (Sandbox Code Playgroud)

 
路线/ init.rb

# encoding: utf-8
require_relative 'login'
require_relative 'main'
Run Code Online (Sandbox Code Playgroud)

 
路线/ 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
Run Code Online (Sandbox Code Playgroud)

 
路线/ main.rb的

# encoding: utf-8
class MyApp < Sinatra::Application
  get "/" do
    @title = "Welcome to MyApp"        
    haml :main
  end
end
Run Code Online (Sandbox Code Playgroud)

 
意见/ 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
Run Code Online (Sandbox Code Playgroud)

  • 我用了不同的方法.编写所有业务逻辑,如ruby中的用户和服务,不需要'sinatra'.这使逻辑独立.然后我使用一个应用程序文件来分配各种类的职责,因此每条路线大约有3行代码.典型应用程序中的路由不多,因此我的应用程序文件实际上并不长. (24认同)
  • 关于上述结构的一个特别好的事情 - 特别是在`models/init.rb`中放置`require"续集"和`DB`初始化,并对所有文件使用`require_relative` - 是你可以进入你的模型`目录,打开IRB控制台并输入`require'./ init'`,然后加载完整的数据库和模型设置以进行交互式探索. (11认同)
  • @ 0xSina在Ruby中并不罕见.你没有"定义"一个类,你"重新打开它".例如,`Array`类是由核心库定义的,但是你可以稍后使用`class Array'来"monkeypatch".def some_awesome_method; 结束`和a)保留所有先前的数组功能,并且b)所有数组实例将获得新代码.Ruby中的类只是对象,可以随时进行扩充和更改. (5认同)

TK-*_*421 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
Run Code Online (Sandbox Code Playgroud)

  • 使用显式的`init.rb`与上面的一个好处是你可以控制加载的顺序,以防你有相互依赖的文件. (7认同)

小智 10

在Google上搜索"Sinatra样板文件",以了解其他人如何布置他们的Sinatra应用程序.从那里你可以找到一个适合你的需求或只是自己做.做起来并不难.随着您开发更多Sinatra应用程序,您可以添加到您的样板.

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

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


Ste*_*cia 7

我知道这是一个古老的查询,但我仍然无法相信没有人提到Padrino你可以将它用作Sinatra之上的框架,或零碎地添加你感兴趣的宝石.它踢了十个屁股!


Sys*_*ank 5

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

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

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

不要低估为您的应用程序使用 gem 模块的力量。您可以在明确界定的环境中轻松测试实验性更改并轻松部署它们。如果出现问题也同样容易恢复。

有一千种方法来组织代码,因此尝试获得类似于 Rails 的布局不会有什么坏处。然而,还有一些关于如何自定义您自己的结构的精彩帖子。这篇文章涵盖了大多数 Web 开发人员的其他常见需求。

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