Reputation: 2210
I'm in the proces of converting my standard Rails app to an mountable engine. The app is comparable to a standard blogging app and i want every model, controller and view to be extendable hence my choice for a mountable engine.
One of the gems i use is Devise which is as far as i understand a sort of a mountable engine itself. It can be used inside a mountable engine as stated here.
I'm able to use it partially within my engine. Everything is working fine including some Devise controller i override like this one:
# config/routes.rb
Bbronline::Engine.routes.draw do
devise_for :users, class_name: "Bbronline::User", module: :devise,
controllers: { registrations: "bbronline/devise_overrides/registrations"}
...
# controllers/bbronline/devise_overrides/registrations_controller.rb
require_dependency "bbronline/application_controller"
module Bbronline
class DeviseOverrides::RegistrationsController < Devise::RegistrationsController
def new_intermediair
@user = User.new
end
...
The correct view 'views/bbronline/devise_overrides/registrations/new_intermediair.html.haml' is also correctly loading as expected.
However my issue is that the views that i override without a custom controller are not properly loaded. For example the view that should the login view is located in views/bbronline/devise/sessions/new.html.haml
and is not loaded. Instead the standard Devise login view gets loaded i.e. devise-2.1.0/app/views/devise/sessions/new.html.erb
Of course i could solve this problem by overriding every controller with my own controller like i did with the registrations_controller above but this seems very ugly. Is overriding every controller the way to do this? Is there a more convenient way to override views from an mountable engine from within another mountable engine?
Upvotes: 6
Views: 2980
Reputation: 5273
If you don't want to adjust the config.railties_order
in every app that uses your engine, just require 'devise'
on top of your lib\my_engine\engine.rb file.
Upvotes: 7
Reputation: 2210
The view_paths are in incorrect order. Checking the view paths of Devise::SessionsController shows:
Devise::SessionsController.view_paths
=> #<ActionView::PathSet:0x007fa1bf0e36f8 @paths= [/Users/harmdewit/Dropbox/Code/projects/brightin/bbr-online/bbr-online-gem/test/dummy/app/views,
/Users/harmdewit/.rbenv/versions/1.9.2-p290/lib/ruby/gems/1.9.1/gems/devise-2.1.0/app/views,
/Users/harmdewit/Dropbox/Code/projects/brightin/bbr-online/bbr-online-gem/app/views]>
The last path of the mountable engine should come before the middle devise path. The solution is setting the loading priority in application.rb like this:
#test/dummy/config/application.rb (the app that uses my mountable engine)
...
config.railties_order = [Blog::Engine, :main_app, :all]
...
This is also documented in the rails api: http://api.rubyonrails.org/classes/Rails/Engine.html#label-Loading+priority
Thanks to José Valim for pointing in the right direction.
Upvotes: 4
Reputation: 51349
I need more information. Which controller are you defining and from which controller is it inheriting from? Which view is being rendered and which one did you expect to render? Also, .view_paths
is your friend so try in your rails console the following:
Devise::SessionsController.view_paths
YourApp::SomeDeviseController.view_paths
This will give you a better idea of where each controller is searching for templates.
Upvotes: 1