Using url_for Outside of the Controller - extend vs include

there is a lot of docs on the web on how to use url_for outside of a
controller. All the examples I saw use it within a class’ instance
methods and they do this by “include” ActionController::UrlWriter.

I want to use it with a class that only has static/class methods. To do
so, I use “extend” instead of “include” which makes all methods of the
module as static methods of the enclosing class.

That sort of worked, url_for was called but it had an error on the first
line (see ‘ERROR OCCURS HERE’ below). Im worried that because I made the
module ‘extend’ some of the inside bits and pieces of
ActionController::UrlWriter are mangled…

When I do this and make the call to url_for, I get this error:

NoMethodError: undefined method `default_url_options’ for Class:Class

Heres some code:

class OutsideController
extend ActionController::UrlWriter # include url_for as a class method
of OutsideController

def self.doit
url = url_for({:controller => ‘controller’, :action => “action”})
end
end

--------------url_for method in UrlWriter module:
def url_for(options)
options = self.class.default_url_options.merge(options) # ERROR
OCCURS HERE

  url = ''

  unless options.delete(:only_path)
    url << (options.delete(:protocol) || 'http')
    url << '://' unless url.match("://")

    raise "Missing host to link to! Please provide :host parameter

or set default_url_options[:host]" unless options[:host]

    url << options.delete(:host)
    url << ":#{options.delete(:port)}" if options.key?(:port)
  else
    # Delete the unused options to prevent their appearance in the

query string.
[:protocol, :host, :port, :skip_relative_url_root].each { |k|
options.delete(k) }
end
trailing_slash = options.delete(:trailing_slash) if
options.key?(:trailing_slash)
url << ActionController::Base.relative_url_root.to_s unless
options[:skip_relative_url_root]
anchor = “##{CGI.escape options.delete(:anchor).to_param.to_s}” if
options[:anchor]
generated = Routing::Routes.generate(options, {})
url << (trailing_slash ? generated.sub(/?|\z/) { “/” + $& } :
generated)
url << anchor if anchor

  url
end

I have tried several things to avoid the error, including also
include/extending extra modules and setting:

extend ActionView::Helpers::UrlHelper
default_url_options[:host] = ‘www.example.com

Obviously I do not understand extend and the inner working of UrlWriter
enough to do this correctly - can anyone help me out?

Mike

Mike P. wrote:

there is a lot of docs on the web on how to use url_for outside of a
controller. All the examples I saw use it within a class’ instance
methods and they do this by “include” ActionController::UrlWriter.

Why do you need to do this? In most cases, it seems to me that
generating URLs in the model os a design problem.

Best,
–Â
Marnen Laibow-Koser
http://www.marnen.org
[email protected]

Hi, the actual place Im using it is to publish some info to Facebook (on
behalf of the user). The text+URL I’m publishing to Facebook have the
URL of the story (on our website).

In this case, this “publish” event happens out-of-band as it is part of
a batch process. The actual code running is not a model but a class in
our lib directory.

One can think of this ‘publish’ as the same thing when we send email on
behalf of our users in a batch process. But for the email case, we CAN
do this:
helper ApplicationHelper because the email class inherits from
ActionMailer::Base

Mike

Marnen Laibow-Koser wrote:

Mike P. wrote:

there is a lot of docs on the web on how to use url_for outside of a
controller. All the examples I saw use it within a class’ instance
methods and they do this by “include” ActionController::UrlWriter.

Why do you need to do this? In most cases, it seems to me that
generating URLs in the model os a design problem.

Best,
–Â
Marnen Laibow-Koser
http://www.marnen.org
[email protected]