Использование рельсов с именами маршрутов и помощников url / view в настраиваемых шаблонах ERB - PullRequest
0 голосов
/ 30 октября 2009

Я мог бы использовать некоторую помощь по включению и расширению модулей и классов 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?

Ответы [ 2 ]

0 голосов
/ 31 октября 2009
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 внутри блока - это MyBigClass, поэтому он фактически создает метод в синглтон-классе MyBigClass. Любой метод в классе singleton не является методом экземпляра.

0 голосов
/ 30 октября 2009

Вызов include из метода класса или блока class_eval приведет к включению определений включенного модуля в сам класс. Я не совсем понимаю, что вы пытаетесь сделать, но, основываясь на вашем описании, я думаю вы делаете это правильно.

...