I could use some help on including and extending Ruby modules and classes.
My previous question handled the named routes, but not all of the view/tag helpers due to the default_url_options
Hash. The issue here is that ActionController::UrlWriter methods, like url_for
, call the class attribute default_url_options
. So when including ActionController::UrlWriter it extends the current class singleton but also needs to extend the current class itself. If you look at my code below, MyBigClass should have the default_url_options on it's class, not instance. This works, but I'm not sure if it's correct or will potentially break something.
Here's my current module:
module MessageViewHelper
module Methods
def self.included(base)
base.module_eval do
include TemplatesHelper
include LegacyUrlsHelper
include ActionView::Helpers::TagHelper
include ActionView::Helpers::AssetTagHelper
include ActionView::Helpers::UrlHelper
include ActionController::UrlWriter
end
MyBigClass.class_eval do
cattr_accessor :default_url_options
def self.default_url_options(options = {})
options.merge({:host=>'www.myhostname.com'})
end
end
unless ActionController::UrlWriter.method_defined?('old_url_for')
ActionController::UrlWriter.class_eval do
alias_method :old_url_for, :url_for
def url_for(options)
if options.is_a?(String)
options
else
old_url_for(options)
end
end
end
end # unless method_defined?
end
end
end
class MyBigClass < ActiveRecord::Base
def message(template_name)
class << self; include MessageViewHelper::Methods; end
# ... more stuff here
end
end
I know I'm not entirely clear on ruby class/module design and extensions. Does anyone have any insight on this? Should the changes on MyBigClass be reverted at the end of message
?