Aumentar un modelo a partir de una joya externa
-
26-09-2019 - |
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?
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