从 Rails 插件向 Rails 引擎模型添加方法

Add methods to a Rails engine model from a Rails plugin

我正在编写一个 Rails 插件来扩展 Rails 引擎。即 MyPlugin 具有 MyEngine 作为依赖项。

在我的 Rails 引擎上,我有一个 MyEngine::Foo 模型。

我想向该模型添加新方法,因此我在我的插件 app/models/my_engine/foo.rb 中创建了一个文件,其中包含以下代码:

module MyEngine
  class Foo

        def sayhi
            puts "hi"
        end

  end
end

如果我在插件虚拟应用程序上输入 Rails 控制台,我可以找到 MyEngine::Foo,但正在运行 MyEngine::Foo.new.sayhi returns

NoMethodError: undefined method `sayhi'

为什么 MyPlugin 看不到 MyEngine::Foo 模型的更新?我哪里错了?

好的,知道了。为了让 MyPlugin 知道并能够修改 MyEngine 模型,插件 engine.rb 上必须需要引擎,如下所示:

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

为了扩展 MyEngine::Foo 模型,我必须创建一个文件 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)

并在 config/initializers/my_engine_extensions.rb

中要求它
require 'my_engine/foo_extension' 

现在从 MyPlugin 我可以:

 MyEngine::Foo.new.sayhi
 => "Hi!"
 MyEngine::Foo.sayhello
 => "Hello!"

有关详细信息,请参阅 ActiveSupport 问题 documentation