为 Sinatra::Base 和 Sinatra::Application Class 共享 ruby 代码



我对Sinatra框架很陌生,我正在尝试做一个与Sinatra::Base&Sinatra::基于应用程序的应用程序。我的gem中有这段代码,它在两个应用程序中都运行良好:

health_check.rb

class App1 < Sinatra::Base
get '/health/liveness' do
halt 204
end
end
class App2 < Sinatra::Application
get '/health/liveness' do
halt 204
end
end

但我的代码是重复的,我想有这样的东西,但它不起作用:

health_check.rb

module HealthHelper
get '/health/liveness' do
halt 204
end
end
class App1 < Sinatra::Base
include HealthHelper
end
class App2 < Sinatra::Application
include HealthHelper
end

当我尝试初始化任何包含gem的应用程序时,我会得到这个错误

/lib/health_check.rb:3:in `<module:HealthHelper>': undefined method `get' for HealthHelper:Module (NoMethodError)
Did you mean?  gets
gem

想让它更干净吗?

您可以编写一个定义路由的Sinatra扩展,而不是简单地使用include

它可能看起来像这样:

require 'sinatra/base'
module HealthHelper
def self.registered(app)
app.get '/health/liveness' do
halt 204
end
end
end
# This line is so it will work in classic Sinatra apps.
Sinatra.register(HealthHelper)

然后在实际的应用程序中,您使用register而不是include:

require 'sinatra/base'
require 'health_helper'
class App1 < Sinatra::Base
register HealthHelper
end

现在,路线将在App1中可用。请注意,您可能不想扩展Sinatra::Application,而是希望扩展Sinatra::Base

经过多次尝试,我找到了一个非常简单的解决方案:

health_check.rb

class Sinatra::Base
get '/health/liveness' do
halt 204
end
end

Sinatra::Application是Sinatra:Base的一个子类,所以我将代码直接包含在Sinatra:Base类定义中。

最新更新