0

我可以在包含和扩展 Ruby 模块和类方面使用一些帮助。

我之前的问题处理了命名路由,但由于default_url_options哈希,并不是所有的视图/标签助手。这里的问题是 ActionController::UrlWriter 方法,例如url_for,调用类属性default_url_options。因此,当包含 ActionController::UrlWriter 时,它扩展了当前类单例,但还需要扩展当前类本身。如果您在下面查看我的代码,MyBigClass 的类上应该有 default_url_options,而不是实例。这可行,但我不确定它是否正确或可能会破坏某些东西。

这是我当前的模块:

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

我知道我对 ruby​​ 类/模块设计和扩展并不完全清楚。有人对此有任何见解吗?MyBigClass 上的更改是否应该在结束时恢复message

4

2 回答 2

0
MyBigClass.class_eval do
  cattr_accessor :default_url_options

  def self.default_url_options(options = {})
     options.merge({:host=>'www.myhostname.com'})
   end
 end

通常,class_eval 在类上定义常规实例方法。

但是,在这种情况下,在 class_eval 块内,您是在 self.xml 上定义方法。块中的 self 是 MyBigClass,所以它实际上会在 MyBigClass 的单例类中创建一个方法。单例类中的任何方法都不是实例方法。

于 2009-10-30T22:27:17.143 回答
0

从类方法或 class_eval 块中调用 include 会将包含模块的定义带入类本身。我不完全理解你想要做什么,但根据你的描述,我认为你做对了。

于 2009-10-30T18:17:01.470 回答