2012-02-10 11 views
22

He creado un motor Rails simple para proporcionar algunas funcionalidades generales (galería de fotos) a una aplicación. Quiero poder anular el parcial de encabezado estándar para que el menú de la galería coincida con el de mi aplicación principal. En mi vista de encabezado, llamo a un ayudante que forma parte de application_helpers (aplicación principal), pero sigo recibiendo errores de "método no definido". Por lo que puedo decir, la aplicación principal de la aplicación no se incluyen (obviamente) cuando anulo el diseño de la aplicación del motor o sus parciales.Acceda a los Ayudantes principales de la aplicación cuando se reemplaza una Vista/diseño de Rails Engine

Así que mi pregunta es, ¿cómo puedo anular una vista de motor en la aplicación principal y obtener acceso a los principales métodos de ayuda de la aplicación? Todavía necesitaría acceder a los ayudantes del motor y no dañar la funcionalidad del motor.

¿Debo anular los controladores también? parece mucho solo para conseguir algunos ayudantes.

Gracias

Rails 3.1.3

+5

Ha intentado 'main_app.your_helper_method'? – glebm

+0

Pruebe el método descrito en esta [pregunta] (http://stackoverflow.com/questions/10879150/isolated-engine-doorkeeper-use-helper-methods-from-the-main-app) si no desea anular los controladores – Matt

Respuesta

1

intentan crear un ayudante en su aplicación con el mismo nombre del ayudante en su motor con el fin de reemplazar los métodos auxiliares del motor.

Encontré this discussion particularmente perspicaz. También hay algunas ideas interesantes en Rails Engine API docs bajo Asistentes de motor aislados.

+0

¡Los documentos de la API Rails Engine me ayudaron a encontrar una buena solución para url_helpers! Gracias. –

2

Intente incluir los principales métodos de ayuda de la aplicación. Por ejemplo:

class MyEngineClass 
    include ApplicationHelper 

    #... 
end 

Es posible que necesite solicitar el archivo primero, aunque esperaría que Rails lo encuentre correctamente en este caso.

Una vez que ApplicationHelper está incluido, debería poder usar directamente esos helpers en el controlador.

También parece que puede llamar al ClassName.helper("application") para una gran cantidad de clases de Rails: no estoy seguro si eso funcionará aquí.

0

Descargo de responsabilidad: Solo he usado esta solución en los motores Rails 3.2.

Si, en su motor tiene un encabezado estándar parcial proveedor/gems/my_gallery_engine/app/views/application/_header.html.erb.

Luego, anule en su aplicación principal creando una aplicación parcial personalizada /views/application/_header.html.erb.

La anulación funciona porque Rails ruta de búsqueda de plantilla de vista (por defecto) comienza con las principales aplicaciones app/views directorio, y luego busca a través de motores app/views en orden de carga.

Todos los Ayudantes de su aplicación principal estarán disponibles en el parcial.

1

Se supone que los motores son independientes de la aplicación principal, es por eso que no se puede acceder a sus ayudantes desde el motor.

Sin embargo, existen formas de hack-ish para dar acceso a su motor a los ayudantes de la aplicación principal.Esto es cómo lo hice:

# In the main app 
# initializers/share_helpers_path_with_engine.rb 
PhotoGallery::Engine.class_eval do 
    paths["app/helpers"] << File.join(File.dirname(__FILE__), '../..', 'app/helpers') 
end 

luego, es preciso cambiar PhotoGallery al nombre real de su clase de motores.

Siéntase libre de echar un vistazo a la documentación de los motores (sección acerca de los caminos): http://edgeapi.rubyonrails.org/classes/Rails/Engine.html

3

la salida esta entrada del blog: http://www.candland.net/2012/04/17/rails-routes-used-in-an-isolated-engine/ El autor añade una definición method_missing a la ayudante de la aplicación con el fin de acceder a los padres ayudantes de la aplicación.

/config/initializers/blogit.rb

module Blogit 
    module ApplicationHelper 
     def method_missing method, *args, &block 
     puts "LOOKING FOR ROUTES #{method}" 
     if method.to_s.end_with?('_path') or method.to_s.end_with?('_url') 
      if main_app.respond_to?(method) 
      main_app.send(method, *args) 
      else 
      super 
      end 
     else 
      super 
     end 
     end 

     def respond_to?(method) 
     if method.to_s.end_with?('_path') or method.to_s.end_with?('_url') 
      if main_app.respond_to?(method) 
      true 
      else 
      super 
      end 
     else 
      super 
     end 
     end 
    end 
    end 
+1

Esto simplemente agrega ayudantes '_path' y' _url', que es todo lo que necesitaba. Sin embargo, hay una mejor solución. Agregue 'helper Rails.application.routes.url_helpers' al' ApplicationController' de su motor. Vea mis comentarios en la publicación de blog vinculada. –

+0

Para OP, probablemente puedas usar la misma técnica para 'helper Rails.application.helpers'. –

Cuestiones relacionadas