Pregunta

Estoy usando refinerycms en nuestro sitio para que el contenido de la actualización del personal menos técnico. Dentro de la gema, que tienen una clase de página que mapea cada página de nivel superior en el sitio. Me gustaría utilizar la gema acts_as_taggable en esta clase de página. Ahora puedo añadir la declaración acts_as_taggle directamente al archivo page.rb, pero entonces tendría que mantener un repositorio git separado para realizar un seguimiento de las diferencias entre mi versión y la versión oficial.

Sobre la base de algunas otras preguntas aquí en lo que he creado un inicializador y la extensión de esta manera:

lib / page_extensions.rb:

module Pants
  module Extensions

    module Page
      module ClassMethods
        def add_taggable
          acts_as_taggable
        end
      end

      def self.included(base)
        base.extend(ClassMethods).add_taggable
      end

    end

  end
end

config / inicializadores / pants.rb

require 'page_extensions'

Page.send :include, Pants::Extensions::Page

app / views / layouts / application.html.erb

...
Tags: <%= @page.tag_list %>

La primera vez que solicita una página desde el servidor emite correctamente todas las etiquetas en la página. Sin embargo, si golpeo refrescar I en lugar de obtener una NoMethodError lo que indica que tag_list no está definido.

Soy nuevo en los carriles así que quizás mis suposiciones son incorrectas, pero esperaba que la llamada a Page.send haría un cambio permanente en la clase de página en lugar de a una instancia específica de la clase. Entonces, ¿cómo puedo obtener el acts_as_taggable añadido a la clase de página en cada petición?

¿Fue útil?

Solución

Se tendrá que poner su código en un bloque module_eval config.to_prepare do. El lugar más fácil de hacer esto es en config/application.rb o para crear un motor. El código es idéntico, excepto que se ejecuta cada vez que se ejecuta el sitio no sólo la primera vez (que se aplica especialmente a modo de desarrollo) y el código que sólo se ejecuta antes de que el proceso de inicialización (archivos) que requieren aka en un bloque config.before_initialize do.

La razón de que config.to_prepare es importante es porque en el modo de desarrollo, el código se vuelve a cargar en cada petición, pero por lo general no son inicializadores. Esto significa que Page, que se está ejecutando un module_eval en adelante, sólo tendrá la carrera module_eval una vez, sino que se recargue en sí todas las solicitudes. config.to_prepare es un gancho de rieles que se ejecuta cada vez que proporciona una gran comodidad para situaciones como ésta.

config / application.rb acercarse

class Application < Rails::Application
  # ... other stuff ...

  config.before_initialize do
    require 'page_extensions'
  end

  config.to_prepare do
    Page.send :include, Pants::Extensions::Page
  end
end

enfoque Motor

Si no desea modificar config/application.rb entonces se puede, en la refinería de CMS, crear vendor/engines/add_page_extensions/lib/add_page_extensions.rb la que se vería así:

require 'refinery'

module Refinery
  module AddPageExtensions
    class Engine < Rails::Engine

      config.before_initialize do
        require 'page_extensions'
      end

      config.to_prepare do
        Page.send :include, Pants::Extensions::Page
      end

    end
  end
end

Si utiliza los motores de acercarse a usted también tendrá que crear vendor/engines/add_page_extensions/add_page_extensions.gemspec que debe contener un gemspec simple:

Gem::Specification.new do |s|
  s.name = 'add_page_extensions'
  s.require_paths = %w(lib)
  s.version = 1.0
  s.files = Dir["lib/**/*"]
end

Y a continuación, en su Gemfile añadir esta línea:

gem 'add_page_extensions', :path => 'vendor/engines'

Si vas el enfoque del motor, es probable que desee poner toda la lógica dentro del directorio lib del motor incluyendo el código Pants::Extensions::Page.

Espero que esto ayude

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top