Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

rails prepend_view_path of mountable engine

In one hand, I have a mountable engine let's say Front Front contain my assets and couple of pages It's isolated from MainApp. I don't want it to touch the main app.

In the other hand I want my MainApp using layout and partial of the Front. So I setup the layout this way :

class ApplicationController < ActionController::Base
    layout 'front/application'
end

But the front/application refer to engine partial directly, because of isolation, like this

render 'header' # front/ prefix is not required

So the MainApp views try to load app/views/application/header instead of app/views/front/application/header

To fixe this I put a prepend_view_path like this :

class ApplicationController < ActionController::Base
    layout 'front/application'
    before_filter :prepend_front
protected
    def prepend_front
       prepend_view_path "app/views/front"
    end
end

But this doesn't work because engine path point into the vendor. The engine add it self this to the prepend path list : ~/main_app/vendor/private_gems/front-0.0.2/app/views And my preprend_front method create this : ~/main_app/app/views/front

I tryed to prepend by force the correct path (but it looks so dirty) :

prepend_view_path "#{Rails.root}/vendor/private_gems/front-0.0.2/app/views/front"

I doesn't work, just crash the app ...

And I'm stuck here. Maybe my design is wrong?

like image 418
ProxyGear Avatar asked Mar 19 '12 11:03

ProxyGear


People also ask

What is Rails engines?

Well, simply put a Rails engine is the miniature edition of a Rails application. It comes with an app folder, including controllers, models, views, routes, migrations... The difference though is, that an engine won't work on its own.

What is Mount in Ruby on Rails?

mount is used to mount another application (basically rack application) or rails engines to be used within the current application.


1 Answers

The answer from Jack is perfect except if you want to do this inside the Rails engine (for example if your engine itself has 'themes' that require a different load path). In this case the prepend_path and append_path are not appropriate since you are going to want to insert your new load path before the engines default load path but after the applications load path.

A solution to this (only tested in Rails 3.2) is to add the following to your engines /lib/my_engine.rb file:

config.after_initialize do
  my_engine_root = MyEngine::Engine.root.to_s
  paths = ActionController::Base.view_paths.collect{|p| p.to_s}
  paths = paths.insert(paths.index(my_engine_root + '/app/views'), my_engine_root + '/app/views/themes/my_theme')
  ActionController::Base.view_paths = paths
end

The new load path my_engine_root + '/app/views/themes/my_theme' will now be just before your engines standard load path my_engine_root + '/app/views'

like image 103
brod Avatar answered Oct 09 '22 02:10

brod