ruby - rails - Usando Sinatra para proyectos más grandes a través de múltiples archivos
sinatra ruby tutorial (8)
Absolutamente. Para ver un ejemplo de esto, recomiendo descargar la gema Monk, que se describe aquí:
https://github.com/monkrb/monk
Puedes "instalarlo gema" a través de rubygems.org. Una vez que tenga la gema, genere una aplicación de muestra usando las instrucciones mencionadas anteriormente.
Tenga en cuenta que no tiene que usar Monk para su desarrollo real a menos que lo desee (de hecho, creo que puede no ser actual). El objetivo es ver cómo puedes estructurar fácilmente tu aplicación en el estilo MVC (con archivos de ruta similares a un controlador por separado) si así lo deseas.
Es bastante simple si nos fijamos en cómo lo maneja Monk, en su mayor parte una cuestión de requerir archivos en directorios separados, algo así como (tendrá que definir el root_path):
Dir[root_path("app/**/*.rb")].each do |file|
require file
end
Parece que en Sinatra todos los manejadores de ruta están siendo escritos en un solo archivo, si entiendo bien, actúa como un controlador grande / pequeño. ¿Hay alguna forma de dividirlo en archivos independientes separados, así que cuando digamos que alguien llama "/" - se ejecuta una acción, y si se recibe algo como "/ posts / 2" entonces otra acción - lógica similar que se aplica en PHP ?
Cuando Monk no trabajó para mí, comencé a trabajar en plantillas yo mismo.
Si lo piensas, no hay nada especial en atar un conjunto de archivos. La filosofía del monje me fue explicada a principios de 2011 durante RedDotRubyConf y me han dicho específicamente que es realmente opcional usarla, especialmente ahora que apenas se mantiene.
Este es un buen comienzo para aquellos que quieran usar ActiveRecord:
Simple Sinatra MVC
Haga una búsqueda en Google de "repetitivo de Sinatra" para obtener algunas ideas sobre cómo otros están diseñando sus aplicaciones Sinatra. De eso, probablemente puedas encontrar uno que se adapte a tus necesidades o simplemente hacer el tuyo. No es muy difícil de hacer. A medida que desarrolles más aplicaciones de Sinatra, puedes agregarlas a tu repetición.
Esto es lo que hice y usé para todos mis proyectos:
La clave de la modularidad en Sinatra para proyectos más grandes es aprender a usar las herramientas subyacentes.
SitePoint tiene un muy buen tutorial desde donde puede ver aplicaciones y ayudantes modulares de Sinatra. Sin embargo, debe prestar especial atención a un detalle importante. Mantiene múltiples aplicaciones de Sinatra y las monta con Rackup. Una vez que sepa cómo escribir una aplicación básica, mire el archivo config.ru de ese tutorial y observe cómo montan aplicaciones independientes de Sinatra.
Una vez que aprenda a ejecutar Sinatra con Rack, se abrirá un nuevo mundo de estrategias de modularidad. Obviamente, esto invita a probar algo realmente útil: ahora puede confiar en tener gemas individuales para cada subaplicación , lo que podría permitirle una versión más fácil de sus módulos.
No subestimes el poder de usar módulos gema para tu aplicación. Puede probar fácilmente cambios experimentales en un entorno bien delimitado y desplegarlos fácilmente. Igualmente fácil de revertir si algo sale mal.
Hay mil maneras de organizar su código, por lo que no estaría de más tratar de obtener un diseño similar al de Rails. Sin embargo, también hay algunos excelentes comentarios sobre cómo personalizar su propia estructura. Esa publicación cubre otras necesidades frecuentes de la mayoría de los desarrolladores web.
Si tiene tiempo, lo aliento a que aprenda más sobre Rack, el terreno común para cualquier aplicación web basada en Ruby. Puede tener un impacto mucho menor en la forma en que hace su trabajo, pero siempre hay ciertas tareas que la mayoría de la gente hace en sus aplicaciones que se adaptan mejor como middleware Rack.
Leyendo los documentos aquí:
Parece que Sinatra le permite descomponer su aplicación en Ruby Modules, que puede extraerse mediante el método de "registro" de Sinatra o los métodos de "ayuda", de esta manera:
helpers.rb
require ''sinatra/base''
module Sinatra
module Sample
module Helpers
def require_logged_in()
redirect(''/login'') unless session[:authenticated]
end
end
end
end
routing / 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
Mi enfoque para alojar diferentes proyectos en el mismo sitio es usar sinatra/namespace
de la siguiente manera:
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
...
Otro detalle sobre los subproyectos que utilicé fue agregar sus nombres, descripción y rutas a algún tipo de variable global, que es usada por "/"
para hacer una página de guía, pero no tengo un fragmento en este momento.
Sé que esta es una consulta antigua, pero todavía no puedo creer que nadie haya mencionado a Padrino Puedes usarla como un marco sobre Sinatra, o de forma fragmentaria añadiendo solo las gemas que te interesan. ¡Lanza diez culos de culo!
Aquí hay una plantilla básica para las aplicaciones de Sinatra que uso. (Mis aplicaciones más grandes tienen más de 200 archivos desglosados de esta manera, sin contar las gemas vendidas, que abarcan de 75 a 100 rutas explícitas. Algunas de estas rutas son rutas Regexp que cubren más de 50 patrones de ruta). Cuando utilizas Thin, ejecutas un aplicación como esta utilizando:
thin -R config.ru start
Editar : ahora estoy manteniendo mi propio esqueleto Monk basado en el siguiente llamado Riblits . Para usarlo para copiar mi plantilla como base para tus propios proyectos:
# Before creating your project
monk add riblits git://github.com/Phrogz/riblits.git
# Inside your empty project directory
monk init -s riblits
Diseño de archivo:
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''
helpers / init.rb
# encoding: utf-8
require_relative ''partials''
MyApp.helpers PartialPartials
require_relative ''nicebytes''
MyApp.helpers NiceBytes
helpers / 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
ayudantes / 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
modelos / 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''
modelos / user.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
rutas / main.rb
# encoding: utf-8
class MyApp < Sinatra::Application
get "/" do
@title = "Welcome to MyApp"
haml :main
end
end
views / 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