常见问题解答
如何使我的 Sinatra 应用程序在更改时重新加载?
首先,在 Ruby 中进行进程内代码重新加载很困难,并且找到适用于所有场景的解决方案在技术上是不可能的。
这就是我们建议您进行进程外重新加载的原因。
首先,如果您还没有安装 rerun,则需要安装它
$ gem install rerun
现在,如果您像这样启动您的 Sinatra 应用程序
$ ruby app.rb
您要做的就是进行重新加载,而不是这样做
$ rerun 'ruby app.rb'
例如,如果您使用的是 rackup
,请执行以下操作
$ rerun 'rackup'
您明白了。
如果您仍然想要进行进程内重新加载,请查看 Sinatra::Reloader。
我的部署选项有哪些?
请参阅 书籍。
如何使用会话?
会话默认情况下是禁用的。您需要启用它们,然后从路由和视图中使用 session
哈希
enable :sessions
get '/foo' do
session[:message] = 'Hello World!'
redirect to('/bar')
end
get '/bar' do
session[:message] # => 'Hello World!'
end
请参阅 Sinatra 自述文件,了解如何为会话设置其他参数,例如会话密钥或过期日期。
您也可以直接使用 Rack::Session::Cookie
,而不是使用 enable :sessions
(来自 Rack 文档的示例)。
use Rack::Session::Cookie, :key => 'rack.session',
:domain => 'foo.com',
:path => '/',
:expire_after => 2592000, # In seconds
:secret => 'change_me'
如何使用基于会话的闪存?
使用 Rack::Flash。
我可以在 Ruby 1.9 下运行 Sinatra 吗?
是的。从 Sinatra 0.9.2 开始,Sinatra 完全兼容 Ruby 1.9 和 Rack 1.0。从 1.1 版本开始,您无需自行处理编码,除非您想这样做。
如何获取当前页面的“路由”?
request
对象可能包含您要查找的内容。
get '/hello-world' do
request.path_info # => '/hello-world'
request.fullpath # => '/hello-world?foo=bar'
request.url # => 'https://example.com/hello-world?foo=bar'
end
有关 request
对象支持的方法的详细列表,请参阅 Rack::Request。
如何在视图中访问助手?
调用它们!视图自动访问所有辅助方法。事实上,Sinatra 在同一个对象上下文中评估路由、视图和辅助方法,因此它们都能够访问相同的方法和实例变量。
在 hello.rb
中
helpers do
def em(text)
"<em>#{text}</em>"
end
end
get '/hello' do
@subject = 'World'
haml :hello
end
在 views/hello.haml
中
%p= "Hello " + em(@subject)
如何渲染部分?
Sinatra 的模板系统非常简单,可以用于页面和片段级别的渲染任务。 erb
和 haml
方法只返回一个字符串。
从 Sinatra 1.1 版本开始,您可以使用与在路由中使用的相同的调用来调用部分。
<%= erb :mypartial %>
在 1.1 版本之前的版本中,您需要确保禁用布局渲染,如下所示
<%= erb :mypartial, :layout => false %>
我可以让多个 URL 触发相同的路由/处理程序吗?
当然可以。
["/foo", "/bar", "/baz"].each do |path|
get path do
"You've reached me at #{request.path_info}"
end
end
说真的。
如何使尾部斜杠可选?
在它后面加上一个问号。
get '/foo/bar/?' do
"Hello World"
end
该路由匹配 "/foo/bar"
和 "/foo/bar/"
。
如何渲染嵌套在子目录中的模板?
Sinatra 应用程序通常在 views
下没有非常复杂的目录层次结构。首先,考虑您是否真的需要子目录。如果是,您可以使用 views/foo/bar.haml
文件作为模板,使用
get '/' do
haml :'foo/bar'
end
这与将 #to_sym
发送到文件名基本相同,也可以写成
get '/' do
haml 'foo/bar'.to_sym
end
我正在运行 Thin,发生错误但没有输出
尝试使用 --debug
参数启动 Thin。
thin --debug --rackup config.ru start
这应该会在 stderr
上为您提供异常和回溯。
如何从 Sinatra 发送电子邮件?
如何使用 Pony (sudo gem install pony
)
require 'pony'
post '/signup' do
Pony.mail :to => '[email protected]',
:from => '[email protected]',
:subject => 'Howdy, Partna!'
end
您甚至可以使用模板来渲染正文。在 email.erb
中
Good day <%= params[:name] %>,
Thanks for signing my guestbook. You're a doll.
Frank
在 mailerapp.rb
中
post '/guestbook/sign' do
Pony.mail :to => params[:email],
:from => "[email protected]",
:subject => "Thanks for signing my guestbook, #{params[:name]}!",
:body => erb(:email)
end
如何转义 HTML?
在你的助手方法中使用 Rack::Utils,如下所示
helpers do
def h(text)
Rack::Utils.escape_html(text)
end
def hattr(text)
Rack::Utils.escape_path(text)
end
end
现在,你可以通过以下两种方式之一在模板中转义输出文本中的 HTML 实体
<div><%= h scary_output %></div>
或者使用 <%==
功能
<div><%== scary_output %></div>
你也可以在模板中像这样转义元素属性中的文本
<a href="<%= hattr scary_output %>" >A nice safe link!</a>
感谢 Chris Schneider 的提示!
如何自动转义 HTML?
需要 Erubis 或 Erubi 并将 escape_html
设置为 true
require 'erubis' # or 'erubi'
set :erb, :escape_html => true
然后,使用 Erubis 渲染的任何模板都会自动转义
get '/' do
erb :index
end
在 Tilt Google Group 上了解更多详细信息。
如何使用 ActiveRecord 迁移?
要将 ActiveRecord 的迁移与 Sinatra(或其他非 Rails 项目)一起使用,请将以下内容添加到你的 Rakefile 中
namespace :db do desc "Migrate the database" task(:migrate => :environment) do ActiveRecord::Base.logger = Logger.new(STDOUT) ActiveRecord::Migration.verbose = true ActiveRecord::Migrator.migrate("db/migrate") end end
这假设你有一个名为
:environment
的任务,它加载你的应用程序的环境(需要正确的文件,设置数据库连接等)。现在,你可以创建一个名为
db/migrate
的目录,并在其中填写你的迁移。我通常将第一个迁移命名为001_init.rb
。(我更喜欢使用旧的顺序方法来对迁移进行编号,而不是自 Rails 2.1 以来使用的日期时间方法,但两种方法都可以。)
有关其他选项,请查看 Sinatra ActiveRecord 扩展。
如何使用 HTTP 身份验证?
你至少有两种选择可以在你的应用程序中实现基本访问身份验证(基本 HTTP 身份验证)。
I. 当你想要保护应用程序中的所有请求时,只需通过 use
指令将 Rack::Auth::Basic 中间件放入请求处理链中
require 'sinatra'
use Rack::Auth::Basic, "Restricted Area" do |username, password|
username == 'admin' and password == 'admin'
end
get '/' do
"You're welcome"
end
get '/foo' do
"You're also welcome"
end
II. 当你想要保护应用程序中的某些 URL,或者想要更复杂的授权时,你可以使用类似于以下内容
require 'sinatra'
helpers do
def protected!
return if authorized?
headers['WWW-Authenticate'] = 'Basic realm="Restricted Area"'
halt 401, "Not authorized\n"
end
def authorized?
@auth ||= Rack::Auth::Basic::Request.new(request.env)
@auth.provided? and @auth.basic? and @auth.credentials and @auth.credentials == ['admin', 'admin']
end
end
get '/' do
"Everybody can see this page"
end
get '/protected' do
protected!
"Welcome, authenticated client"
end
如何测试 HTTP 身份验证?
假设你在你的 application.rb
中有这个简单的 HTTP 身份验证实现
require 'sinatra'
use Rack::Auth::Basic do |username, password|
username == 'admin' and password == 'admin'
end
get '/protected' do
"You're welcome"
end
你可以使用 Rack::Test 像这样测试它
ENV['APP_ENV'] = 'test'
require 'test/unit'
require 'rack/test'
require 'application'
class ApplicationTest < Test::Unit::TestCase
include Rack::Test::Methods
def app
Sinatra::Application
end
def test_without_authentication
get '/protected'
assert_equal 401, last_response.status
end
def test_with_bad_credentials
authorize 'bad', 'boy'
get '/protected'
assert_equal 401, last_response.status
end
def test_with_proper_credentials
authorize 'admin', 'admin'
get '/protected'
assert_equal 200, last_response.status
assert_equal "You're welcome", last_response.body
end
end