182 votes

Utilisation de Sinatra pour les grands projets via des fichiers multiples

Il semble que dans Sinatra, tous les gestionnaires de route sont écrits dans un seul fichier, si je comprends bien, il agit comme un seul grand/petit contrôleur. Y a-t-il un moyen de le diviser en fichiers indépendants séparés, de sorte que lorsque quelqu'un appelle "/", une action est exécutée, et si quelque chose comme "/posts/2" est reçu, une autre action est exécutée - une logique similaire à celle appliquée en PHP ?

394voto

Phrogz Points 112337

Voici un modèle de base pour les applications Sinatra que j'utilise. (Mes applications les plus importantes ont plus de 200 fichiers répartis comme ceci, sans compter les gemmes vendues, couvrant 75-100 routes explicites. Certaines de ces routes sont des routes Regexp couvrant plus de 50 modèles de routes supplémentaires). Lorsque vous utilisez Thin, vous exécutez une application comme celle-ci en utilisant :
thin -R config.ru start

Modifier : Je maintiens maintenant mon propre Moine squelette basé sur l'appel ci-dessous Riblits . Pour l'utiliser, copiez mon modèle comme base pour vos propres projets :

# Before creating your project
monk add riblits git://github.com/Phrogz/riblits.git

# Inside your empty project directory
monk init -s riblits

Mise en page du fichier :

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'

 
aides/init.rb

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

require_relative 'nicebytes'
MyApp.helpers NiceBytes

 
aides/partiels.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

 
aides/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

 
modèles/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'

 
modèles/utilisateur.rb

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

 
routes/init.rb

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

 
routes/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

 
routes/main.rb

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

 
vues/layout.haml

!!! XML
!!! 1.1
%html(xmlns="http://www.w3.org/1999/xhtml")
  %head
    %title= @title
    %link(rel="icon" type="image/png" href="http://stackoverflow.com/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

10voto

TK-421 Points 2848

Absolument. Pour voir un exemple de ceci, je recommande de télécharger la gemme Monk, décrite ici :

https://github.com/monkrb/monk

Vous pouvez l'installer via rubygems.org. Une fois que vous avez la gemme, générez un exemple d'application en utilisant les instructions liées ci-dessus.

Notez que vous n'êtes pas obligé d'utiliser le Moine pour votre développement réel, à moins que vous ne le souhaitiez (en fait, je pense que ce n'est peut-être pas d'actualité). Le but est de voir comment vous pouvez facilement structurer votre application dans le style MVC (avec des fichiers de route séparés de type contrôleur) si vous le souhaitez.

C'est assez simple si vous regardez comment Monk le gère, il s'agit principalement de demander des fichiers dans des répertoires séparés, quelque chose comme (vous devrez définir root_path) :

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

10voto

Robert Ziehl Points 51

Faites une recherche Google sur "Sinatra boilerplate" pour avoir une idée de la manière dont les autres conçoivent leurs applications Sinatra. À partir de là, vous pourrez probablement en trouver un qui réponde à vos besoins ou simplement créer le vôtre. Ce n'est pas très difficile à faire. Au fur et à mesure que vous développerez des applications Sinatra, vous pourrez compléter votre modèle.

Voici ce que j'ai fait et que j'utilise pour tous mes projets :

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

7voto

Steven Garcia Points 920

Je sais que c'est une vieille question mais je ne peux toujours pas croire que personne n'a mentionné Padrino Vous pouvez l'utiliser comme un cadre de travail au-dessus de Sinatra, ou y ajouter au coup par coup les éléments qui vous intéressent. C'est une véritable bombe à retardement !

1voto

kgpdeveloper Points 675

Quand Monk n'a pas fonctionné pour moi, j'ai commencé à travailler sur des modèles moi-même.

Si vous y réfléchissez, il n'y a rien de spécial à attacher un ensemble de fichiers. La philosophie du moine m'a été expliquée début 2011 lors de la RedDotRubyConf et ils m'ont spécifiquement dit qu'il est vraiment facultatif de l'utiliser, surtout maintenant qu'elle est à peine maintenue.

C'est un bon début pour ceux qui veulent utiliser ActiveRecord :

Simple Sinatra MVC

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X