Кажется, что в Sinatra все обработчики маршрутов записываются в один файл, если я правильно понимаю, он действует как один большой/маленький контроллер. Есть ли способ разделить его на отдельные независимые файлы, поэтому, если скажем, что кто-то называет "/" - выполняется одно действие, и если smth нравится "/posts/2", то другое действие - аналогичная логика, применяемая в PHP
Использование Sinatra для больших проектов через несколько файлов
Ответ 1
Вот базовый шаблон для приложений Sinatra, которые я использую. (В моих более крупных приложениях было создано более 200 файлов, не считая драгоценных камней вендоров, охватывающих 75-100 явных маршрутов. Некоторые из этих маршрутов - это маршруты регулярного выражения, содержащие дополнительные 50+ шаблонов маршрута.) При использовании Thin вы запускаете приложение, как это, используя: 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
Ответ 2
Совершенно верно. Чтобы увидеть пример этого, я рекомендую загрузить камень Monk, описанный здесь:
https://github.com/monkrb/monk
Вы можете 'gem install' его через rubygems.org. После того, как у вас есть драгоценный камень, сгенерируйте пример приложения, используя приведенные выше инструкции.
Обратите внимание, что вам не нужно использовать Monk для вашей реальной разработки, если вы этого не хотите (на самом деле, я думаю, что это может быть не актуально). Дело в том, чтобы увидеть, как вы можете легко структурировать свое приложение в стиле MVC (с отдельными файлами маршрутов, подобными контроллеру), если вы хотите.
Это довольно просто, если вы посмотрите на то, как Monk обрабатывает его, в основном вопрос о необходимости файлов в отдельных каталогах, что-то вроде (вам нужно определить root_path):
Dir[root_path("app/**/*.rb")].each do |file|
require file
end
Ответ 3
Сделайте поиск Google для "шаблона Sinatra", чтобы получить некоторые идеи о том, как другие излагают свои приложения Sinatra. Из этого вы, вероятно, можете найти тот, который соответствует вашим потребностям или просто сделать свой собственный. Это не слишком сложно сделать. Когда вы разрабатываете больше приложений Sinatra, вы можете добавить к своему шаблону.
Вот что я сделал и использовал для всех моих проектов:
Ответ 4
Я знаю, что это старый запрос, но я до сих пор не могу поверить, что никто не упоминал Padrino. Вы можете использовать его в качестве основы для вершине Синатры, или по частям, добавляя только драгоценные камни, которые вас интересуют. Он пинает десять задниц задницы!
Ответ 5
Ключом к модульности Sinatra для более крупных проектов является изучение использования основных инструментов.
SitePoint имеет очень хорошее хорошее руководство, из которого вы можете видеть модульные приложения и помощники Sinatra. Однако вы должны обратить особое внимание на одну важную деталь. Вы сохраняете несколько приложений Sinatra и монтируете их с помощью Rackup. Как только вы знаете, как написать базовое приложение, посмотрите файл config.ru этого учебника и посмотрите, как они монтируют независимые приложения Sinatra.
Как только вы научитесь запускать Sinatra со стойкой, откроется новый мир стратегий модульности. Это, очевидно, предлагает попробовать что-то действительно полезное: теперь вы можете полагаться на наличие отдельных Gems для каждого дополнительного приложения, что может позволить вам легко модифицировать ваши модули.
Не стоит недооценивать возможности использования gem-модулей для вашего приложения. Вы можете легко протестировать экспериментальные изменения в хорошо разграниченной среде и легко развернуть их. В равной степени легко вернуться назад, если что-то пойдет не так.
Существует тысячи способов организовать ваш код, поэтому не мешало бы получить макет, похожий на Rails. Однако есть и некоторые отличные сообщения о том, как настроить свою собственную структуру. Эта публикация охватывает другие частые потребности большинства веб-разработчиков.
Если у вас есть время, я рекомендую вам узнать больше о Rack, общей для любого веб-приложения на основе Ruby. Это может оказать гораздо меньшее влияние на то, как вы выполняете свою работу, но всегда есть определенные задачи, которые большинство людей делают в своих приложениях, которые лучше подходят для промежуточного ПО Rack.
Ответ 6
Мой подход к размещению разных проектов на одном сайте - это использование 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
...
Другая информация о подпроектах, которые я использовал, заключалась в том, чтобы добавить их имена, описания и маршруты к какой-либо глобальной переменной, которая используется "/"
для создания главной страницы руководства, но сейчас у меня нет фрагмента.
Ответ 7
Когда Монк не работал у меня, я сам начал работать над шаблонами.
Если вы думаете об этом, нет ничего особенного в связывании набора файлов. Философия монаха была объяснена мне в начале 2011 года во время RedDotRubyConf, и они специально сказали мне, что действительно необязательно использовать ее, особенно сейчас, когда ее почти не поддерживают.
Это хорошее начало для тех, кто хочет использовать ActiveRecord:
Простая Sinatra MVC
Ответ 8
Чтение документов здесь:
Похоже, что Sinatra позволяет разложить ваше приложение на Ruby Modules, которое можно втянуть через метод "register" 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