Mam silnik, który definiuje niektóre modele i sterowniki. Chcę móc rozszerzyć funkcjonalność niektórych modeli/kontrolerów w mojej aplikacji (np. Dodawanie metod) bez utraty oryginalnego modelu/kontrolera z silnika. Wszędzie czytałem, że po prostu trzeba zdefiniować kontroler o tej samej nazwie w aplikacji i Railsy automatycznie je scalą, jednak nie działa to dla mnie i kontroler w silniku jest po prostu ignorowany (nie sądzę, że jest on załadowany).Silniki szynowe rozszerzające funkcjonalność
Odpowiedz
Tylko czy ktoś pracuje w tej samej kwestii jakiś czas w przyszłości, to jest Kod pisałem, że stały mój problem:
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
Spowoduje to automatyczne wymagają plików z silnikiem przed wymagając od aplikacji, jeśli ścieżka do pliku zaczyna się od „app”.
To prawda. Zostanie użyty sterownik, który zostanie znaleziony jako pierwszy.
Więc aby to działało może masz dwie opcje:
- utworzyć lokalną kopię sterownika i zmodyfikować metodę trzeba
- jeśli masz kontrolę nad wtyczką, można utworzyć Moduł zawierający kod i include kod w obu kontrolerach, tylko przesłonięcie metody w lokalnym kontrolerze. Według mnie, ponieważ nie ma dziedziczenia wielokrotnego, jest to jedyny sposób.
Mam nadzieję, że to pomoże.
nigdy nie używane silniki wcześniej, ale nie można zdefiniować nowy kontroler, który dziedziczy ze sterownika dostarczonego przez silnik
Nie, jeśli mają taką samą nazwę. – Andrius
Co zrobić, jeśli są w oddzielnej przestrzeni nazw? –
Możesz dodać te linie do ciebie plik modułu silnika w lib katalogu:
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
Wtedy masz możliwość w głównej aplikacji (dzięki czemu aplikacja korzysta z silnika) żądania niezbędnych plików z silnika. Jest to miłe, ponieważ zachowujesz domyślną funkcjonalność Rails Engines, a także masz proste narzędzie do korzystania z normalnego dziedziczenia ruby, bez potrzeby stosowania łatek.
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"
jaka jest korzyść z robienia tego w ten sposób w porównaniu z GŁÓWNYM modelem APP dziedziczącym z modelu ENGINE? – westonplatter
Jeśli plik MODA.rb znajduje się w aplikacji GŁÓWNEJ, a aplikacja ENGINE, ale APP ENGINE .rb nie jest wymagana w aplikacji GŁÓWNEJ .rb, Railsy ignorują APP ENGINE .rb. Aplikacja ENGINE to MAIN nie podąża za normalnym dziedzictwem ruby, przynajmniej wtedy, gdy napisałem tę odpowiedź. – joshmckin
Podoba mi się to rozwiązanie! Moje pytanie brzmi: co jeśli użytkownik w silniku w nazwach? – user3281384
require MyEngine::Engine.root.join('app', 'models', 'my_engine', 'my_model')
przed definicją klasy modelu w aplikacji.
Możesz zmienić kolejność ładowania silnika, aby uniknąć wymagań w każdym z modeli.
W config/environment.rb dodać ten wiersz:
module MyApp
class Application
config.railties_order = [MyEngine::Engine, :main_app, :all]
end
end
Zapewni to, że modele z MyEngine są ładowane przed MojaApl
O ile mi wiadomo, automatyczne ładowanie Railsów znajduje pierwszą definicję (model silnika w twoim przypadku) i używa go, nie przechodzi przez inne ścieżki, aby załadować możliwe inne definicje tego samego modelu. – linkyndy
- 1. Szynowe powiązanie STI z podklasami
- 2. Silniki 2D dla Javascriptu
- 3. Silniki do gier 2D XNA
- 4. Friendly ID i poręcze Silniki
- 5. Szynowe powiązania polimorficzne bez typu (unikalny identyfikator)
- 6. Ruby: moduły rozszerzające/zawierające moduły
- 7. PHP-OOP rozszerzające dwie klasy?
- 8. "Metody rozszerzające" w Objective-C
- 9. rozszerzające oddziaływania czynników w formule
- 10. Działanie rozszerzające ActionBarActivity i YouTubeBaseActivity
- 11. Drzewa decyzyjne i silniki reguł (Drools)
- 12. Silniki gier 3D dla Ruby lub Python?
- 13. Czy zoptymalizowano połączenia ogłaszane przez silniki JavaScript?
- 14. Które silniki są używane w większych przeglądarkach?
- 15. Jak działają silniki renderujące 2d ze skanowaniem?
- 16. Silniki i struktury do eksploracji danych?
- 17. Funkcje rekursywne i listy dołączające/rozszerzające
- 18. Eclipse - znajdź wszystkie klasy rozszerzające interfejs
- 19. Domyślne metody i interfejsy rozszerzające inne interfejsy
- 20. JavaScript: Typy rozszerzające - Cel "zwróć to"
- 21. Funkcjonalność XmlSerializer w PowerShell?
- 22. Elasticsearch - poprzednia/następna funkcjonalność
- 23. Funkcjonalność jądra linuksa
- 24. Funkcjonalność void operator()()
- 25. Hibernate postgresql powiadamia funkcjonalność
- 26. Czy mogę zawiesić funkcjonalność iScroll?
- 27. Czy można ograniczyć funkcjonalność DLL?
- 28. Funkcjonalność PHP `preg_match_all` w Javie
- 29. SandCastle Help Builder: Funkcjonalność wyszukiwania
- 30. Geany intellisense Funkcjonalność dla C++
To rozwiązanie działa dla Rails 3, zobacz http://stackoverflow.com/questions/5045068/extending-controllers-of-a-rails-3-engine-inhe -main-app – Andrei
Teraz działa również dla Rails 3. – Andrei
Z tej odpowiedzi stworzyłem klejnot około roku temu, ale zapomniałem go opublikować tutaj. Działa to dobrze dla nas: https://github.com/EPI-USE-Labs/activesupport-decorators –