Josh
Josh

Reputation: 530

Extending the functionality of a model in a mounted rails engine

UPDATE 3:

This solution seems ugly but I moved the decorator back to the decorators directory and then just added this to my application controller:

require './app/decorators/models/monologue/post_decorator.rb'
include ExtendPost
require './app/decorators/controllers/monologue/admin/posts_controller_decorator.rb'
include ExtendAdminPostsController

Thoughts for how to do this properly? Thanks.

But at least this works.

UPDATE 2:

Well the following worked, but could someone please explain how to put this code in the "right" place and not where I stuck it:

In my application_controller.rb in my main_app, I now have:

class ApplicationController < ActionController::Base 

end

Monologue::PostsRevision.class_eval do
   validates :title, :length => {:maximum => 25} 
end

This works properly, but is in a bad location from an organizational / code readability standpoint.

UPDATE:

I also tried something different based on the SO answer here and ended up with this code, which also did not work:

In app/models/post_revision.rb (again, in main_app's app folder)

require Monologue::PostRevisions::Engine.config.root + 'app' + 'models' + 'page'
class PostRevision
    validates :title, :length => {:maximum => 25} 
end

This did not work either.

When attempting to modify the functionality of a mounted engine in Rails 3 using decorators and the class_eval method, are the decorators supposed to go in the app folder in your main_app or in the app folder in your engine?

I am attempting to modify some of the models in an engine called Monologue that I got here. I found a good explanation of how to do that on the site of a different product (Refinery) here. And I also followed the instructions at this Rails Guide.

So the code I ended up with was:

In lib/monologue/engine.rb (is this supposed to be in the lib folder in the main app or the engine? I put it in the lib folder in my main_app):

module Monologue
    class Engine < ::Rails::Engine
        isolate_namespace Monologue

        config.to_prepare do
            Dir.glob(Rails.root + "app/decorators/**/*_decorator*.rb").each do |c|
                require_dependency(c)
            end
        end
   end
end  

And in app/decorators/monologue/posts_revisions_decorator.rb (and again, I put this in the app folder in the main_app, not the Monologue engine app folder):

Monologue::PostsRevision.class_eval do
   validates :title, :length => {:maximum => 25} 
end

But this does not work. The additional validation does nothing.

If this is because it is supposed to go within the folders in the Monologue mounted engine and not the main_app, than I don't know how to do that since those files are not in my main_app directory.

Thoughts? Thanks.

Upvotes: 4

Views: 1184

Answers (2)

Pierre Pretorius
Pierre Pretorius

Reputation: 2909

An alternative is the activesupport-decorators gem.

Upvotes: 2

dbenton
dbenton

Reputation: 313

I was able to overcome a similar challenge by loading my decorator via to_prepare in an initializer. Try something like this:

# /config/initializers/my_engine.rb
Rails.application.config.to_prepare do
  require_dependency("./app/decorators/models/my_engine/my_model_decorator.rb")
end

Upvotes: 3

Related Questions