So I have an engine which defines some models and controllers. I want to be able to extend functionality of some models/controllers in my application (eg. adding methods) without loosing the original model/controller functionality from engine. Everywhere I read that you simply need to define controller with the same name in your application and Rails will automatically merge them, however it doesn't work for me and controller in engine is simply ignored (I don't think it's even loaded).
A:
That is true. The controller that is found first will be used.
So to make it work you might have two options:
- create a local copy of the controller, and modify the method you need
- if you have control over the plugin, you could create a Module containing the code and include the code in both controllers, only overriding the method in your local controller. According to me, since there is no multiple inheritance, that is the only way.
Hope this helps.
nathanvda
2010-06-03 10:14:25
A:
I've never used Engines before but can't you define a new controller that inherits from the controller provided by the engine
Steve Weet
2010-06-03 10:51:31
Not if they have the same name.
Andrius
2010-06-03 11:41:30
What about if they're in a seperate Namespace
Steve Weet
2010-06-03 13:03:36
A:
Just if anyone else runs into same issue some time in the future, this is the code I wrote that fixed my 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
This will automatically require files from engine before requiring from application if file path starts with 'app'.
Andrius
2010-06-07 14:53:47