2012-02-10 8 views
22

Ho creato un semplice motore Rails per fornire alcune funzionalità generali (galleria fotografica) a un'applicazione. Voglio essere in grado di sovrascrivere il partial _header standard in modo che il menu della galleria corrisponda a quello della mia applicazione principale. Nella mia vista dell'header chiamo un helper che fa parte di application_helpers (app principale), ma continuo a ricevere errori "metodo indefinito". Da quello che posso dire l'app principale application_helpers non viene inclusa (ovviamente) quando sovrascrivo il layout dell'applicazione dei motori oi suoi partial.Accesso agli helper delle app principali in caso di overriding a Rails Engine View/Layout

Quindi la mia domanda è: come sovrascrivere una visualizzazione motore nell'applicazione principale e accedere ai metodi di supporto dell'applicazione principale? Avrei comunque bisogno di accedere agli helper del motore e di non rovinare la funzionalità del motore.

Devo sovrascrivere anche i controller? sembra un sacco solo per avere alcuni aiutanti.

Grazie

Rails 3.1.3

+5

Hai provato 'main_app.your_helper_method'? – glebm

+0

Prova il metodo descritto in questa [domanda] (http://stackoverflow.com/questions/10879150/isolated-engine-doorkeeper-use-helper-methods-from-the-main-app) se non vuoi sostituisci i controller – Matt

risposta

1

provare a creare un assistente nella vostra applicazione con lo stesso nome della aiutante nel motore, al fine di sovrascrivere i metodi helper del motore.

Ho trovato this discussion particolarmente penetranti. Ci sono anche alcune idee interessanti nello Rails Engine API docs sotto Aiutanti del motore isolato.

+0

I documenti API di Rails Engine mi hanno aiutato a trovare una buona soluzione per url_helpers! Grazie. –

2

Provare a includere i metodi di supporto delle app principali. Per esempio:

class MyEngineClass 
    include ApplicationHelper 

    #... 
end 

Si può eventualmente necessario richiedere il file prima, anche se mi sarei aspettato Rails per trovare correttamente in questo caso.

Una volta che ApplicationHelper è incluso, dovresti essere in grado di utilizzare direttamente questi helper nel controller.

Sembra anche che si possa chiamare ClassName.helper("application") per molte classi di Rails - non è sicuro se funzionerà qui.

0

Disclaimer: Ho usato questa soluzione solo nei motori Rails 3.2.

Se nel motore è presente un'intestazione standard parziale vendor/gems/my_gallery_engine/app/views/application/_header.html.erb.

Quindi, esegui l'override nell'app principale creando un'app parziale/personalizzata app/views/application/_header.html.erb.

L'override funziona perché Rails percorso di ricerca vista modello (per impostazione predefinita) inizia con le principali applicazioni app/views directory, e quindi ricerca attraverso i motori app/views in ordine di caricamento.

Tutti gli Helpers dell'app principale saranno disponibili nel parziale.

1

I motori dovrebbero essere indipendenti dall'app principale, ecco perché non è possibile accedere ai relativi helper dal motore.

Tuttavia, esistono modi di hacking per consentire al proprio motore di accedere agli helper dell'app principale.Ecco come ho fatto:

# 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 

È necessario, naturalmente, per cambiare PhotoGallery per il nome effettivo della classe del motore.

Sentitevi liberi di dare un'occhiata alla documentazione Motori (sezione riguardante i percorsi): http://edgeapi.rubyonrails.org/classes/Rails/Engine.html

3

check-out questo post del blog: http://www.candland.net/2012/04/17/rails-routes-used-in-an-isolated-engine/ L'autore aggiunge una definizione method_missing per l'assistente di applicazione al fine di accedere al genitore aiutanti dell'applicazione.

/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

Questo aggiunge solo gli helper '_path' e' _url', che è tutto ciò di cui avevo bisogno. C'è una soluzione migliore però. Aggiungi 'helper Rails.application.routes.url_helpers' al' ApplicationController' del tuo motore. Vedi i miei commenti sul post del blog collegato. –

+0

Per OP, probabilmente potresti usare la stessa tecnica con 'helper Rails.application.helpers'. –

Problemi correlati