Tengo un motor que define algunos modelos y controladores. Quiero poder ampliar la funcionalidad de algunos modelos/controladores en mi aplicación (por ejemplo, agregar métodos) sin perder la funcionalidad del modelo/controlador original del motor. Dondequiera que lea, simplemente necesita definir el controlador con el mismo nombre en su aplicación y Rails los fusionará automáticamente, sin embargo, no funciona para mí y el controlador en el motor simplemente se ignora (no creo que esté siquiera cargado).Motores Rails que amplían la funcionalidad
Respuesta
Sólo si alguien más se topa mismo problema algún momento en el futuro, este es el código que he escrito que fija mi 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
Esto requerirá automáticamente los archivos de motor antes de que requiere de la aplicación si la ruta del archivo comienza con 'app'.
Eso es cierto. El controlador que se encuentra primero se usará.
Así que para que funcione es posible que tenga dos opciones:
- crear una copia local del controlador, y modificar el método que necesita
- si tiene control sobre el plugin, se puede crear una Módulo que contiene el código y include el código en ambos controladores, solo reemplaza el método en su controlador local. Según mi opinión, dado que no hay herencia múltiple, esa es la única forma.
Espero que esto ayude.
nunca he utilizado los motores antes, pero no se puede definir un nuevo controlador que herede desde el controlador proporcionado por el motor
No si tienen el mismo nombre. – Andrius
¿Qué pasa si están en un Namespace separado? –
Puede añadir estas líneas para archivo de módulo de motor en el directorio raíz 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
Entonces usted tiene la habilidad en la aplicación principal (la toma de aplicación uso del motor) para exigir que los archivos necesarios del motor. Esto es bueno porque mantiene la funcionalidad predeterminada de Rails Engines y también tiene una herramienta fácil para hacer uso de la herencia de Ruby normal, sin la necesidad de parches.
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"
¿cuál es el beneficio de hacerlo de esta manera en comparación con el modelo de APP PRINCIPAL que hereda del modelo ENGINE? – westonplatter
Si un archivo model.rb está presente en la APLICACIÓN PRINCIPAL y en la APLICACIÓN DEL MOTOR pero la APLICACIÓN DEL MOTOR .rb no se requiere en la APLICACIÓN PRINCIPAL .rb, Rails ignora la APLICACIÓN DEL MOTOR .rb. La aplicación ENGINE to MAIN no sigue la herencia ruby normal, al menos cuando escribí esta respuesta. – joshmckin
¡Me gusta esta solución! Mi pregunta es: ¿y si el usuario en el motor está en el espacio de nombres? – user3281384
require MyEngine::Engine.root.join('app', 'models', 'my_engine', 'my_model')
antes de la definición de clase del modelo en la aplicación.
Puede cambiar el orden de carga del motor para evitar el requerimiento en cada uno de sus modelos.
En config/application.rb añadir esta línea:
module MyApp
class Application
config.railties_order = [MyEngine::Engine, :main_app, :all]
end
end
Esto asegurará que los modelos de MyEngine se cargan antes de MiApl
Por lo que sé, Rails carga automáticamente la primera definición (el modelo del motor en su caso) y la usa, no pasa por las otras rutas para cargar otras posibles definiciones del mismo modelo. – linkyndy
- 1. Contacto funcionalidad en Rails 3
- 2. Rails 3.1 - Desarrollo con motores montables
- 3. Sobrecarga de activos en motores Rails: requiere que falle un archivo de activos de gema secundario
- 4. carriles 3.1.1 motores: con motores montables, ¿es posible acceder a los recursos de la aplicación principal, diseño predeterminado?
- 5. WaitHandle.WaitAny para que coincida con la funcionalidad WaitForMultipleObjects
- 6. Marca: Q! tienen la misma funcionalidad que: q! en vim
- 7. ¿Las interfaces principales de Java EE 7 (EntityManager, ...) amplían AutoClosable?
- 8. .Net gobierna motores
- 9. Motores 2D para Javascript
- 10. ¿Cómo sobrescribir la funcionalidad window.open?
- 11. Emulando la funcionalidad de ShowDialog
- 12. ¿Hay motores de plantillas de Scala que no sean scalate?
- 13. ¿El método de carga jquery proporciona la funcionalidad ajax equivalente al método Rails replace_html?
- 14. ¿Cómo implementaría una funcionalidad similar a la url_for de Rails con Clojure y sus frameworks web?
- 15. Incrustar la funcionalidad de su sitio en otros con Rails 3 (XSS vs iframes)
- 16. gema para OAuth2 Consumidor y la funcionalidad del proveedor en Rails 2.3.5
- 17. En Rails, ¿cómo comprueba la funcionalidad de un formato de respuesta de Javascript?
- 18. Rails Motores de plantillas para el usuario final: Liquid vs Moustache vs. Others?
- 19. Motores polimórficos, en idiomas administrados?
- 20. Evite que Ruby on Rails 3 analice la publicación JSON
- 21. Recomendación Motores para aplicaciones Java
- 22. Cómo integrar la funcionalidad "¿Quiso decir?" En los rieles?
- 23. Motores de plantillas de Javascript que funcionan con la Política de seguridad de contenido de Chrome
- 24. ¿Cómo implementar la funcionalidad de deshacer?
- 25. Buscando la funcionalidad PostMessage en Qt
- 26. ¿Debería incorporarse la funcionalidad GExperts a Delphi?
- 27. Simulando la funcionalidad packusdw con SSE2
- 28. Asp.net: Implementando la funcionalidad de Auto-Logout
- 29. implementando la funcionalidad SIP en IOS5
- 30. buscando la funcionalidad de autocompletar en emacs
Esta solución funciona para Rails 3, ver http://stackoverflow.com/questions/5045068/extending-controllers-of-a-rails-3-engine-in-the -main-app – Andrei
Ahora también funciona para Rails 3. – Andrei
Creé una joya de esta respuesta hace aproximadamente un año, pero olvidé de publicarla aquí. Funciona bien para nosotros: https://github.com/EPI-USE-Labs/activesupport-decorators –