devise_invitable - Rails url 在 DeviseInvitable 控制器的应用程序布局中找不到助手
devise_invitable - Rails url helpers not found in application layout in DeviseInvitable controller
我正在写一个 Rails 引擎(订阅),它将成为多租户 Rails 应用程序的基础,并处理子域、帐户、用户(使用 Devise)和订阅。
除了 devise_invitable Devise::InvitationsController 呈现应用程序布局时,一切正常。发生这种情况时,布局渲染会崩溃并出现以下错误:
未定义局部变量或方法`destroy_user_session_path'
我不知道为什么 url 助手在此上下文中不可用,因为它们似乎可用于应用程序的其余部分。
应用程序布局仍然可以访问 current_user 等 Devise 变量,如果我删除 link 到 destroy_user_session_path 邀请#新动作使布局很好。
虚拟应用程序 (spec/dummy) 中的 运行 "rake routes" 正确显示路线。我还尝试了以下方法:
- 使用 "binding.pry" 在应用程序布局本身内撬动并插入断点。 "show-routes" 仍然正确显示路线。
- 用我自己的控制器重写 Devise::InvitationsController 并手动包含 Rails URL 助手无济于事。
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
可在此处找到当前正在进行的工作的完整源代码(README.md 已过时):
在 Devise 控制器的上下文中,路径似乎必须是带有引擎名称的名称spaced。
将 destroy_user_session_path 更改为 subscribe.destroy_user_session_path 即可解决问题。
由于引擎是 namespaced,因此还需要覆盖 devise_invitable 中包含的默认视图(例如 app/views/devise/mailer/invitation_instructions.html.erb),因为它们使用root_url 等路由在这种情况下不存在。
这也是所有 Devise 控制器的情况,例如Devise SessionsController 也不会在顶级名称 space.
中找到这些路由
我正在写一个 Rails 引擎(订阅),它将成为多租户 Rails 应用程序的基础,并处理子域、帐户、用户(使用 Devise)和订阅。
除了 devise_invitable Devise::InvitationsController 呈现应用程序布局时,一切正常。发生这种情况时,布局渲染会崩溃并出现以下错误: 未定义局部变量或方法`destroy_user_session_path'
我不知道为什么 url 助手在此上下文中不可用,因为它们似乎可用于应用程序的其余部分。
应用程序布局仍然可以访问 current_user 等 Devise 变量,如果我删除 link 到 destroy_user_session_path 邀请#新动作使布局很好。
虚拟应用程序 (spec/dummy) 中的运行 "rake routes" 正确显示路线。我还尝试了以下方法:
- 使用 "binding.pry" 在应用程序布局本身内撬动并插入断点。 "show-routes" 仍然正确显示路线。
- 用我自己的控制器重写 Devise::InvitationsController 并手动包含 Rails URL 助手无济于事。
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
可在此处找到当前正在进行的工作的完整源代码(README.md 已过时):
在 Devise 控制器的上下文中,路径似乎必须是带有引擎名称的名称spaced。
将 destroy_user_session_path 更改为 subscribe.destroy_user_session_path 即可解决问题。
由于引擎是 namespaced,因此还需要覆盖 devise_invitable 中包含的默认视图(例如 app/views/devise/mailer/invitation_instructions.html.erb),因为它们使用root_url 等路由在这种情况下不存在。
这也是所有 Devise 控制器的情况,例如Devise SessionsController 也不会在顶级名称 space.
中找到这些路由