I'm writing a Rails plugin to extend a Rails engine. Namely MyPlugin
has MyEngine
as a dependency.
On my Rails engine I have a MyEngine::Foo
model.
I'd like to add new methods to this model so I created a file in my plugin app/models/my_engine/foo.rb
which has the following code:
module MyEngine
class Foo
def sayhi
puts "hi"
end
end
end
If I enter the Rails console on the plugin dummy application I can find MyEngine::Foo
, but runnning MyEngine::Foo.new.sayhi
returns
NoMethodError: undefined method `sayhi'
Why MyPlugin
cannot see the updates to MyEngine::Foo
model? Where am I wrong?
Ok, found out. To make MyPlugin
aware and able to modify MyEngine
models the engine must be required on the plugin engine.rb
like so:
require "MyEngine"
module MyPlugin
class Engine < ::Rails::Engine
isolate_namespace MyPlugin
# You can also inherit the ApplicationController from MyEngine
config.parent_controller = 'MyEngine::ApplicationController'
end
end
In order to extend MyEngine::Foo
model I then had to create a file lib/my_engine/foo_extension.rb
:
require 'active_support/concern'
module FooExtension
extend ActiveSupport::Concern
def sayhi
puts "Hi!"
end
class_methods do
def sayhello
puts "Hello!"
end
end
end
::MyEngine::Foo(:include, FooExtension)
And require it in config/initializers/my_engine_extensions.rb
require 'my_engine/foo_extension'
Now from MyPlugin
I can:
MyEngine::Foo.new.sayhi
=> "Hi!"
MyEngine::Foo.sayhello
=> "Hello!"
See ActiveSupport Concern documentation for more details.