How to access URL helper from rails module

前端 未结 5 923
感情败类
感情败类 2020-12-25 10:42

I have a module with a function. It resides in /lib/contact.rb:

module Contact
  class << self
    def run(current_user)
      ...
    end
  end
end


        
相关标签:
5条回答
  • 2020-12-25 11:05

    I've been struggling with the niceties the helper is expecting from the default controller and stack (default_url_options, etc.), and didn't want to hardcode the host.

    Our URL helpers are provided by our nifty module, of course:

    include Rails.application.routes.url_helpers
    

    But include this as is, and (1) the helper is going to look for default_url_options, and (2) won't know about the request host nor the request.

    The host part comes from the controller instance's url_options. Hence, I pass the controller context into my former module, now a class:

    class ApplicationController
      def do_nifty_things
        HasAccessToRoutes.new(self).render
      end
    end
    
    class HasAccessToRoutes
      include Rails.application.routes.url_helpers
      delegate :default_url_options, :url_options, to: :@context
    
      def initialize(context)
        @context = context
      end
    
      def render
        nifty_things_url
      end
    end
    

    Might not fit every case, but it's been useful to me when implementing a sort of custom renderer.

    In any way:

    • if you want access to the default url options seamlessly, or the host of the request, you need to pass controller/request context in
    • if you just need the path, no host, and don't care about the url options, you can just make some dummy methods.
    0 讨论(0)
  • 2020-12-25 11:18
    delegate :url_helpers, to: 'Rails.application.routes' 
    url_helpers.users_url  => 'www.foo.com/users'
    

    to Augustin Riedinger, that delegation code needs to refer to url_helpers (plural), otherwise you get

    undefined method `url_helper'

    0 讨论(0)
  • 2020-12-25 11:22

    Delegation to url_helpers seems much better than including the whole module into your model

    delegate :url_helpers, to: 'Rails.application.routes' 
    url_helpers.users_url  => 'www.foo.com/users'
    

    reference

    0 讨论(0)
  • 2020-12-25 11:26

    Here is how I do it in any context without include

    routes = Rails.application.routes.url_helpers
    url = routes.some_path
    

    That works in any context. If you're trying to include url_helpers - make sure you are doing that in the right place e.g. this works

    module Contact
      class << self
        include Rails.application.routes.url_helpers
      end
    end
    

    and this does not work

    module Contact
      include Rails.application.routes.url_helpers
      class << self
      end
    end
    

    One more example with Capybara tests

    feature 'bla-bla' do
      include Rails.application.routes.url_helpers
      path = some_path #unknown local variable some_path
    end
    

    and now the right one

    include Rails.application.routes.url_helpers
    feature 'bla-bla' do
      path = some_path #this is ok
    end
    
    0 讨论(0)
  • 2020-12-25 11:28

    In your module, just perform a :

     include Rails.application.routes.url_helpers
    
    0 讨论(0)
提交回复
热议问题