Ho un motore che definisce alcuni modelli e controller. Voglio essere in grado di estendere la funzionalità di alcuni modelli/controller nella mia applicazione (ad esempio aggiungendo metodi) senza perdere la funzionalità del modello/controller originale dal motore. Ovunque legga, devi semplicemente definire un controller con lo stesso nome nella tua applicazione e Rails le unirà automaticamente, tuttavia non funziona per me e il controller nel motore viene semplicemente ignorato (non penso nemmeno che sia caricato).Rails engine estendendo le funzionalità
risposta
Proprio se qualcun altro si imbatte in stesso problema qualche tempo in futuro, questo è il codice che ho scritto che risolto il mio problema:
module ActiveSupport::Dependencies
alias_method :require_or_load_without_multiple, :require_or_load
def require_or_load(file_name, const_path = nil)
if file_name.starts_with?(RAILS_ROOT + '/app')
relative_name = file_name.gsub(RAILS_ROOT, '')
@engine_paths ||= Rails::Initializer.new(Rails.configuration).plugin_loader.engines.collect {|plugin| plugin.directory }
@engine_paths.each do |path|
engine_file = File.join(path, relative_name)
require_or_load_without_multiple(engine_file, const_path) if File.file?(engine_file)
end
end
require_or_load_without_multiple(file_name, const_path)
end
end
Ciò richiederà automaticamente i file dal motore prima di richiedere dall'applicazione se il percorso del file inizia con 'app'.
Questo è vero. Verrà utilizzato il controller che viene trovato per primo.
Quindi, per farlo funzionare si potrebbe avere due opzioni:
- creare una copia locale del controller, e modificare il metodo è necessario
- se si ha il controllo del plug-in, è possibile creare un Modulo contenente il codice e include il codice in entrambi i controller, solo sovrascrivendo il metodo nel controller locale. Secondo me, poiché non c'è eredità multipla, questa è l'unica via.
Spero che questo aiuti.
non ho mai usato Motori di prima, ma non si può definire un nuovo controller che eredita dal controller fornita dal motore
Non se hanno lo stesso nome. – Andrius
Che dire se si trovano in uno spazio dei nomi separato –
È possibile aggiungere queste righe a voi file di modulo del motore nella directory principale lib:
def self.root
File.expand_path(File.dirname(File.dirname(__FILE__)))
end
def self.models_dir
"#{root}/app/models"
end
def self.controllers_dir
"#{root}/app/controllers"
end
Quindi si avrà la possibilità nel ricorso principale (l'rendendo app uso del motore) per richiedere i file necessari dal motore. Questo è bello perché si mantiene la funzionalità predefinita di Rails Engines e si ha anche uno strumento semplice per fare uso dell'ereditarietà di ruby normale, senza bisogno di patch.
EX:
#ENGINE Model -
class User < ActiveRecord::Base
def testing_engine
puts "Engine Method"
end
end
#MAIN APP Model -
require "#{MyEngine.models_dir}/user"
class User
def testing_main_app
puts "Main App Method"
end
end
#From the Main apps console
user = User.new
puts user.testing_engine #=> "Engine Method"
puts user.tesing_main_app #=> "Main App Method"
qual è il vantaggio di farlo in questo modo rispetto al modello APP principale che eredita dal modello ENGINE? – westonplatter
Se un file model.rb è presente nell'APP PRINCIPALE e nell'APP ENGINE ma l'APP MOTORE .rb non è richiesta nell'API principale .rb, Rails ignora l'APP MOTORE .rb. L'app ENGINE to MAIN non segue la normale ereditarietà di ruby, almeno quando ho scritto questa risposta. – joshmckin
Mi piace questa soluzione! La mia domanda è: cosa succede se l'utente nel motore in namespace? – user3281384
require MyEngine::Engine.root.join('app', 'models', 'my_engine', 'my_model')
prima della definizione della classe del modello nell'applicazione.
È possibile modificare l'ordine di caricamento del motore per evitare il fabbisogno su ciascun modello.
in config/application.rb aggiungere questa riga:
module MyApp
class Application
config.railties_order = [MyEngine::Engine, :main_app, :all]
end
end
Questo farà sì che i modelli da MyEngine vengono caricati prima MyApp
Per quanto ne so, l'autoloading di Rails trova la prima definizione (il modello del motore nel tuo caso) e la usa, non passa attraverso gli altri percorsi per caricare possibili altre definizioni dello stesso modello. – linkyndy
- 1. Posso usare le funzionalità di C++ estendendo Python?
- 2. Helpers in Rails engine
- 3. Contattaci funzionalità in Rails 3
- 4. Rails engine/Come usare seed?
- 5. ExtJS - creazione di un pacchetto estendendo le classi in un'app
- 6. ActiveSupport :: Prevenendo ed estendendo il modello mongoid
- 7. Sostituire le funzionalità del PIL (ImageDraw) in Google App Engine (GAE)
- 8. Si sta estendendo una classe singleton errata?
- 9. Distribuzione dell'app Ruby on Rails su Google App Engine
- 10. Ruby on Rails User Management Engine/Framework? (con pagine Web)
- 11. Quali sono le funzionalità utili di Emacs per lo sviluppo di Rails
- 12. Incorporare le funzionalità del tuo sito in anothers con Rails 3 (XSS vs iframes)
- 13. Quali sono le funzionalità più interessanti di Ruby on Rails, perché sceglierlo?
- 14. Gem Vs Plugin Vs Engine in Ruby on Rails
- 15. Riferimento per le istruzioni x86 per funzionalità
- 16. Disabilitare le funzionalità estese con iTextSharp
- 17. le funzionalità di due righe di codice
- 18. Le funzionalità di XmlSerializer in PowerShell?
- 19. git flow che rilascia le funzionalità selezionate
- 20. Flex mobile supporta le funzionalità mobili native?
- 21. MomentJS come funzionalità per le app Android
- 22. estendere le funzionalità JConsole per le connessioni remote client
- 23. Uso di creazione di un thread estendendo una classe Thread
- 24. Rendere l'unità Symfony2 test più ASCIUTTO estendendo WebTestCase
- 25. Scopo di avere figli astratti estendendo il genitore concreto
- 26. Aggiungi array 2D a array 3D, estendendo la terza dimensione
- 27. Accesso agli helper delle app principali in caso di overriding a Rails Engine View/Layout
- 28. Django & App Engine - 2012 Refresh
- 29. App Engine mappatura URL
- 30. Corretto da GOPATH per includere le librerie App Engine da App Engine SDK?
Questa soluzione funziona per Rails 3, vedere http://stackoverflow.com/questions/5045068/extending-controllers-of-a-rails-3-engine-in-the -main-app – Andrei
Ora funziona anche per Rails 3. – Andrei
Ho creato una gemma da questa risposta circa un anno fa ma ho dimenticato di postarla qui. Funziona bene per noi: https://github.com/EPI-USE-Labs/activesupport-decorators –