I am writing on a Rails engine (Subscribe) which will be the base of a multi-tenant Rails app and handle subdomains, accounts, users (with Devise) and subscriptions.
Everything works fine except for when the devise_invitable Devise::InvitationsController renders the application layout. When this happens, the layout rendering crashes with errors such as: undefined local variable or method `destroy_user_session_path'
I have no idea why the url helpers are not available in this context as they seem available for the rest of the application.
The application layout still have access to Devise variables such as current_user and if I remove the link to destroy_user_session_path the invitation#new action renders the layout just fine.
Running "rake routes" within the dummy application (spec/dummy) shows the routes correctly. I have also tried the following:
- Use pry and insert a breakpoint using "binding.pry" inside the application layout itself. "show-routes" still shows the routes correctly.
- Override Devise::InvitationsController with my own controller and included the Rails URL helpers manually to no avail.
config/routes.rb
require 'subscribe/constraints/subdomain_required'
require 'subscribe/constraints/no_subdomain'
Subscribe::Engine.routes.draw do
constraints Subscribe::Constraints::SubdomainRequired do
scope module: "account" do
root to: "dashboard#index", as: :account_root
end
devise_for :users,
class_name: "Subscribe::User",
module: :devise,
path: "/",
:controllers => { :invitations => 'subscribe/user_invitations' }
resources :users
end
spec/dummy: 'rake routes'
Routes for Subscribe::Engine:
account_root GET / subscribe/account/dashboard#index
new_user_session GET /sign_in(.:format) devise/sessions#new
user_session POST /sign_in(.:format) devise/sessions#create
destroy_user_session DELETE /sign_out(.:format) devise/sessions#destroy
user_password POST /password(.:format) devise/passwords#create
new_user_password GET /password/new(.:format) devise/passwords#new
edit_user_password GET /password/edit(.:format) devise/passwords#edit
PATCH /password(.:format) devise/passwords#update
PUT /password(.:format) devise/passwords#update
accept_user_invitation GET /invitation/accept(.:format) subscribe/user_invitations#edit
remove_user_invitation GET /invitation/remove(.:format) subscribe/user_invitations#destroy
user_invitation POST /invitation(.:format) subscribe/user_invitations#create
new_user_invitation GET /invitation/new(.:format) subscribe/user_invitations#new
PATCH /invitation(.:format) subscribe/user_invitations#update
PUT /invitation(.:format) subscribe/user_invitations#update
users GET /users(.:format) subscribe/users#index
POST /users(.:format) subscribe/users#create
new_user GET /users/new(.:format) subscribe/users#new
edit_user GET /users/:id/edit(.:format) subscribe/users#edit
user GET /users/:id(.:format) subscribe/users#show
PATCH /users/:id(.:format) subscribe/users#update
PUT /users/:id(.:format) subscribe/users#update
DELETE /users/:id(.:format) subscribe/users#destroy
config/initializers/devise.rb
config.parent_controller = 'Subscribe::ApplicationController'
config.router_name = :subscribe
config.scoped_views = true
spec/dummy/app/views/layouts/application.html.slim
doctype html
html
head
title
= javascript_include_tag "application", "data-turbolinks-track" => true
= csrf_meta_tags
body
- flash.each do |k,v|
div class = "flash #{k}"
= v
br
- binding.pry
- if user_signed_in?
= "Signed in as #{current_user.email}"
= link_to "Sign out", destroy_user_session_path, method: :delete
- else
= "Not signed in"
br
== yield
app/controllers/subscribe/user_invitations_controller.rb
module Subscribe
class UserInvitationsController < Devise::InvitationsController
include Rails.application.routes.url_helpers
include Rails.application.routes.mounted_helpers
def new
#binding.pry
super
end
end
end
subscribe.gemspec
$:.push File.expand_path("../lib", __FILE__)
# Maintain your gem's version:
require "subscribe/version"
# Describe your gem and declare its dependencies:
Gem::Specification.new do |s|
s.name = "subscribe"
s.version = Subscribe::VERSION
s.authors = ["author"]
s.email = ["author@example.com"]
s.homepage = "https://.com"
s.summary = "Subscriber engine for .com"
s.description = "..."
s.files = Dir["{app,config,db,lib}/**/*", "MIT-LICENSE", "Rakefile", "README.rdoc"]
#Framework
s.add_dependency "rails", "~> 4.1.0"
#Auth
s.add_dependency "devise", "~>3.5.0"
s.add_dependency "devise_invitable", "~>1.5.5"
s.add_dependency "pundit", "~>0.2.3"
#Layout and interface
s.add_dependency "slim-rails", "~> 2.1.2"
s.add_dependency "jquery-rails", "~> 3.1.4"
#Testing
s.add_development_dependency "rspec-rails", "~> 3.0.0"
s.add_development_dependency "capybara", "~> 2.3.0"
s.add_development_dependency "capybara-screenshot", "~> 0.3.17"
s.add_development_dependency "factory_girl_rails", "~> 4.4.1"
s.add_development_dependency "database_cleaner", "~> 1.2.0"
#Tools and support
s.add_development_dependency "spring", "~> 1.1.3"
s.add_development_dependency "spring-commands-rspec"
s.add_development_dependency "sqlite3"
s.add_development_dependency "better_errors"
s.add_development_dependency "binding_of_caller"
s.add_development_dependency "pry-rails"
#s.add_development_dependency "guard-rspec" - does not work atm
s.add_development_dependency "rb-inotify"
s.add_development_dependency "libnotify"
end
app/controllers/subscribe/application_controller.rb
module Subscribe
class ApplicationController < ActionController::Base
layout "application"
protect_from_forgery with: :exception
end
end
Full source for current work-in-progress can be found here (README.md is outdated):