author avatar

sachin.kabadi

Mon Jul 29 2024

How to override models in parent application by reopening existing Rails engine classes. This can be done by organising overrides in a dedicated directory (e.g., app/overrides), ignoring this directory in the autoloader, and preloading the overrides in a to_prepare callback.


# config/application.rb
module MyApp
  class Application < Rails::Application
    # ...

    overrides = "#{Rails.root}/app/overrides"
    Rails.autoloaders.main.ignore(overrides)

    config.to_prepare do
      Dir.glob("#{overrides}/**/*_override.rb").sort.each do |override|
        load override
      end
    end
  end
end


To override an engine model, such as Blog::Article:


# Blog/app/models/blog/article.rb
module Blog
  class Article < ApplicationRecord
    # ...
  end
end


Create a file that reopens the class:


# MyApp/app/overrides/models/blog/article_override.rb
Blog::Article.class_eval do
  # ...
end


Using class_eval ensures we are reopening the class or module, not redefining it.

#rails #rails-engines