【问题标题】:How to extend middleware to custom classes outside the MVC scope (Rails)?如何将中间件扩展到 MVC 范围(Rails)之外的自定义类?
【发布时间】:2014-06-02 15:15:06
【问题描述】:

我正在使用 gem omniauth-shopify-oauth2 连接到 Shopify 的 API。

config/initializers/shopify.rb 我正在设置我的OmniAuth::Builder 像这样:

Rails.application.config.middleware.use OmniAuth::Builder do
  provider :shopify, "my_shopify_api_key", "my_shopify_secret",
    scope: 'read_orders',
    setup: lambda { |env| params = Rack::Utils.parse_query(env['QUERY_STRING'])
                        env['omniauth.strategy'].options[:client_options][:site] = "http://#{params['shop']}" }
end

然后我可以从任何控制器文件访问 Shopify 的 API,如下所示:

omniauth = request.env['omniauth.auth']
if omniauth && omniauth[:provider] && omniauth[:provider] == "shopify"
  token     = omniauth['credentials'].token
  session   = ShopifyAPI::Session.new("#{username}.myshopify.com", token)
  ShopifyAPI::Base.activate_session(session)
  # Do stuff with the session
  ShopifyAPI::Base.clear_session
end

另一方面,如果我将控制器功能移动到例如app/my_custom_folder/my_custom_file.rb我在第一行代码中遇到错误:

NameError (undefined local variable or method `request' for #<MyCustomClass:0x007fe07ec11f68>):

我假设引发错误是因为我的自定义类和文件无法访问中间件功能。那么如何扩展功能呢?

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-4 middleware


    【解决方案1】:

    Rails 自动需要某些目录中的所有内容,但 my_custom_folder 不是其中之一。

    您可以在config/application.rb 中添加类似的内容

    config.autoload_paths += %W(
      #{config.root}/my_custom_folder
    )
    

    或者,您可以将my_custom_file.rb 放在像app/controllers/concerns 这样的祝福位置

    另外:

    在我看来,您移至 my_custom_file.rb 的代码可能还希望位于可以访问 request(通过 ActionController::Base)的控制器内。

    在不知道my_custom_file.rb 长什么样的情况下,我建议您将其设置为像这样的包含:

    # in app/controllers/concerns/my_custom_file.rb
    module MyCustomFile
      extend ActiveSupport::Concern
    
      included do
        # if necessary to run stuff on include:
        # before_action :do_some_oauth_shopify_stuff
      end
    
      # This will be treated as part of all controllers now:
      def do_some_oauth_shopify_stuff
        # your code
      end
    end
    
    # near top of app/controllers/application_controller.rb
    class ApplicationController < ActionController::Base
      include MyCustomFile
      # rest of application_controller.rb
    end
    

    也许为模块/文件选择一个更好的名称。

    【讨论】:

    • 感谢您的回答。但是也会出现同样的错误。
    • @ChristofferJoergensen 在 ALSO 下更新了我的答案:希望对您有所帮助!
    猜你喜欢
    • 1970-01-01
    • 2013-01-25
    • 2017-05-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多