简体   繁体   English

在自定义呈现的ERB模板中使用命名为rails的rails和url / view helper

[英]Using rails named routes and url/view helpers within custom rendered ERB templates

I could use some help on including and extending Ruby modules and classes. 我可以在包括和扩展Ruby模块和类方面使用一些帮助。

My previous question handled the named routes, but not all of the view/tag helpers due to the default_url_options Hash. 我的上一个问题处理的是命名路由,但由于default_url_options哈希值,因此无法处理所有视图/标签助手。 The issue here is that ActionController::UrlWriter methods, like url_for , call the class attribute default_url_options . 这里的问题是ActionController :: UrlWriter方法(如url_for )调用类属性default_url_options So when including ActionController::UrlWriter it extends the current class singleton but also needs to extend the current class itself. 因此,当包含ActionController :: UrlWriter时,它可以扩展当前类的单例,但也需要扩展当前类本身。 If you look at my code below, MyBigClass should have the default_url_options on it's class, not instance. 如果您在下面查看我的代码,MyBigClass应该在其类(而不是实例)上具有default_url_options。 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. 我知道我对ruby类/模块设计和扩展尚不完全清楚。 Does anyone have any insight on this? 有人对此有见识吗? Should the changes on MyBigClass be reverted at the end of message ? message末尾是否应还原MyBigClass上的更改?

Calling include from within a class method or a class_eval block will bring the included module's definitions into the the class itself. 从类方法或class_eval块中调用include将把包含的模块定义带入类本身。 I don't completely understand what you're trying to do, but based on your description, I think you're doing it correctly. 我不完全了解您要做什么,但是根据您的描述,我认为您做得正确。

MyBigClass.class_eval do
  cattr_accessor :default_url_options

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

Normally, a class_eval defines regular instance methods on the class. 通常,class_eval在类上定义常规实例方法。

But, in this case inside the class_eval block you are defining the method on self. 但是,在这种情况下,您将在class_eval块中定义self的方法。 self inside the block is MyBigClass, so it would actually create a method in MyBigClass's singleton class. 块中的self是MyBigClass,因此它实际上将在MyBigClass的单​​例类中创建一个方法。 Any method in the singleton class is not an instance method. 单例类中的任何方法都不是实例方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM