How to call url_for from outside of a controller?

B Benj Bouch 3 years 6 months ago
84 1 0

Greetings,

I need to call from a plain ruby class (not a RhoController) the following code:

    Rho::WebView.navigate(url_for controller: 'Blah', action: 'index')

which get me an `undefined method url_for` error.
If I replace the `url_for` by its literal "/app/Blah/index" it works ok and navigates to the target page, but I'd like to keep using `url_for` because of conditional query parameters and such

I even try using `Rho::RhoController.new.url_for ...` but, as expected, it won't work

Any suggestion appreciated, thanks in advance.

Please Register or Login to post a reply

1 Replies

J Jon Tara

url_for is an instance method  defined in Rho::RhoController and so is only available in controllers. And, clearly, some features do not make sense if it were available outside of controllers. For example, the application and model default if not specified based in the request. Clearly, if there is no controller instance, there is no request that can be examined.

It's a pretty small bit of code, and so you might want to extract it and rewrite it for the more general case. So, in your rewritten version, you should always require a model option.

I think this would be a useful feature in Rhodes. I agree url_for should be usable outside of a controller (with obvious limitations), but the current code cannot be used in that context.

    # Examples of how to use url_for method:
    #
    # url_for '/some_url'
    # ==> /some_url
    #
    # When generating a new URL, missing values may be filled in from the current request's parameters.
    # For example, if application name or model are not specifyed in the call parameters, they would be filled from the request.
    #
    # url_for :action => :index
    # ==> /application/model
    #
    # url_for :action => :create
    # ==> /application/model
    #
    # url_for :action => :new
    # ==> /application/model/new
    #
    # url_for :action => :show, :id => '{12}'
    # ==> /application/model/{12}/show
    #
    # url_for :model => :another_model, :action => :show, :id => '{12}'
    # ==> /application/another_model/{12}/show
    #
    # url_for :controller => :another_controller, :action => :show, :id => '{12}'
    # ==> /application/another_controller/{12}/show
    #
    # url_for :application => :another_app, :model => :another_model, :action => :show, :id => '{12}'
    # ==> /another_app/another_model/{12}/show
    #
    # url_for :action => :create, :query => {:name => 'John Smith', 'address' => "http://john.smith.com"}
    # ==> /application/model?name=John%20Smith&address=http%3A%2F%2Fjohn.smith.com
    #
    # url_for :action => :show, :id => '{12}', :fragment => "an-anchor"
    # ==> /application/model/{12}/show#an-anchor
    #
    def url_for(params = {})
      return params.to_s if params.is_a?( String ) or params.is_a?( Symbol )
      return '/' if not params.is_a?( Hash ) or params.nil?

      params = params.symbolize_keys if params.is_a? Hash

      application = params[:application] || @request['application']
      model = params[:controller] || params[:model] || @request['model']
      action = params[:action].nil? ? nil : params[:action].to_s
      id = params[:id].nil? ? nil : params[:id].to_s
      id = "{#{id}}" if id and not( id =~ /^{/ and id =~ /}$/ )

      if params[:query_s]
        query = params[:query_s]
      else
        query = query_to_s(params[:query])
      end
      
      fragment = params[:fragment].nil? ? '' : '#' + params[:fragment]

      amurl = ''
      amurl

CONTACT
Can’t find what you’re looking for?