【问题标题】:devise_invitable - Rails url helpers not found in application layout in DeviseInvitable controllerdevise_invitable - 在 DeviseInvitable 控制器的应用程序布局中找不到 Rails url 帮助程序
【发布时间】:2016-02-22 09:58:26
【问题描述】:

我正在编写 Rails 引擎 (Subscribe),它将成为多租户 Rails 应用程序的基础,并处理子域、帐户、用户(使用 Devise)和订阅。

除了 devise_invitable Devise::InvitationsController 呈现应用程序布局时,一切正常。发生这种情况时,布局渲染会崩溃并出现以下错误: 未定义的局部变量或方法 `destroy_user_session_path'

我不知道为什么 url 助手在这种情况下不可用,因为它们似乎可用于应用程序的其余部分。

应用程序布局仍然可以访问设计变量,例如 current_user,如果我删除指向 destroy_user_session_path 的链接,invitation#new 操作会很好地呈现布局。

在虚拟应用程序 (spec/dummy) 中运行“rake routes”可以正确显示路由。我还尝试了以下方法:

  • 使用 pry 并在应用程序布局本身中使用“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 已过时):

https://github.com/heliohm/Subscribe

【问题讨论】:

    标签: ruby-on-rails devise devise-invitable


    【解决方案1】:

    在 Devise 控制器的上下文中,路径似乎必须使用引擎名称命名。

    subscribe.destroy_user_session_path 更改 destroy_user_session_path 可以解决问题。

    由于引擎是命名空间的,因此还需要覆盖 devise_invitable 中包含的默认视图(例如 app/views/devise/mailer/invitation_instructions.html.erb),因为它们使用诸如 root_url之类的路由> 在这种情况下不存在。

    这也是所有设计控制器的情况,例如Devise SessionsController 也不会在顶级名称空间中找到这些路由。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-11-02
      • 2015-12-07
      • 2012-12-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-20
      相关资源
      最近更新 更多