如何在Sinatra视图中使用gem中的函数?

时间:2013-07-09 16:26:04

标签: ruby-on-rails ruby gem sinatra

问题here询问如何将Rails视图辅助函数提取到gem中,并且接受答案非常好。

我想知道 - 如何为Sinatra做同样的事情?我正在创建一个在模块中定义了一堆辅助函数的gem,我想让这些函数可用于Sinatra视图。但无论我尝试什么,我似乎都无法访问这些函数,我只得到undefined local variable or method错误。

到目前为止,我的宝石结构看起来像这样(其他东西,如gemspec省略):

cool_gem/
  lib/
    cool_gem/
      helper_functions.rb
      sinatra.rb 
  cool_gem.rb

cool_gem.rb中,我有:

if defined?(Sinatra) and Sinatra.respond_to? :register
  require 'cool_gem/sinatra'
end

helper_functions.rb中,我有:

module CoolGem
  module HelperFunctions

    def heading_tag(text)
      "<h1>#{text}</h1>"
    end

    # + many more functions
  end
end

sinatra.rb中,我有:

require 'cool_gem/helper_functions'

module CoolGem
  module Sinatra

    module MyHelpers
      include CoolGem::HelperFunctions
    end

    def self.registered(app)
      app.helpers MyHelpers
    end

  end
end

这不起作用。我哪里错了?

(如果你想知道,是的,我需要一个单独的文件中的辅助函数。我打算让gem兼容Rails,所以我想保持函数隔离/解耦,如果可能的话)。

1 个答案:

答案 0 :(得分:2)

您主要是错过了对Sinatra.register的调用(cool_gem/sinatra.rb中):

require 'sinatra/base'
require 'cool_gem/helper_functions'

module CoolGem
  # you could just put this directly in the CoolGem module if you wanted,
  # rather than have a Sinatra sub-module
  module Sinatra

    def self.registered(app)
      #no need to create another module here
      app.helpers CoolGem::HelperFunctions
    end

  end
end

# this is what you're missing:
Sinatra.register CoolGem::Sinatra

现在任何需要cool_gem的经典风格Sinatra应用程序都可以使用帮助程序。如果您使用模块化样式,则还需要在register CoolGem::Sinatra子类内调用Sinatra::Base

在这种情况下,如果您只是提供一些辅助方法,更简单的方法可能是使用helpers方法(再次在cool_gem/sinatra.rb中):

require 'sinatra/base'
require 'cool_gem/helper_functions'

Sinatra.helpers CoolGem::HelperFunctions

现在这些方法将在经典风格的应用中提供,模块化风格的应用需要调用helpers CoolGem::HelperFunctions。这有点简单,但如果要向DSL上下文添加方法,则需要使用上面的registered