![](/img/trans.png)
[英]No route matches error but rake routes finds it, Rails.application.routes recognises it
[英]Devise routing: is there a way to remove a route from Rails.application.routes?
devise_for
创建包含DELETE路由的路由,我们要删除它, devise_for
不支持:except
或:only
选项。
如何从Rails.application.routes
删除路由? 在draw
块中,还是之后?
以下是错误的详细信息,这是我们需要删除路由的原因。
我们向自定义UJS控制器操作发出DELETE请求
在控制器操作中,我们删除了我们想要的内容,然后执行302重定向。 这是一个坏主意,我们已经通过返回一些JSON来纠正它。
这个错误已经修复,但我想删除路由。
以下是我最后所做的事情,这是由何塞·瓦利姆引用的赏金获胜者所建议的:
在config/routes.rb
,我在devise_for
调用上面添加了这个,它设置了其余的'people'
路由:
delete '/person', :to => 'people#destroy'
然后在我现有的people_controller.rb
,我添加了一个no-op方法:
def destroy
render :nothing => true
end
我仍然有点恼火,没有一种简单的方法可以从RouteSet中删除路由。 此外,设备控制器仍然存在delete
路由,但它不会被调用,因为rails在config/routes.rb
查找第一个匹配并返回它。
以下是Jose Valim(设计的作者) 就此主题所说的话 :
无法单独删除路线。 或者您使用:跳过全部删除并手动绘制您需要的路径,或者通过在config / routes.rb中首先定义到同一路径的路由来覆盖此路由。
所以对你的问题的简短回答是否定的,你不能删除那条路线。 你当然可以尝试修补devise_for方法,但这将是一个有点参与的事业(一天或几个努力)。 我只是使用:skip选项,然后实现你想要的那个控制器的路由,而不是那个你没有的路由。
是的,有点。 您可以完全覆盖使用的设备控制器并编写您自己的设备(如果需要,继承Devise)。 这个维基页面可以作为指导。
为什么我说有点:)
覆盖会话使用:
devise_for :users, :controllers => { :sessions => 'custom_devise/sessions'}, :skip => [:sessions] do
get 'sign_in' => 'custom_devise/sessions#new', :as => :new_user_session
post 'sign_in' => 'custom_devise/sessions#create', :as => :user_session
end
只给你两条路线[:get,:post],但不是:destroy
new_user_session GET /sign_in(.:format) {:controller=>"custom_devise/sessions", :action=>"new"}
user_session POST /sign_in(.:format) {:controller=>"custom_devise/sessions", :action=>"create"}
所以,实际上,你跳过了破坏/删除路由。 现在在控制器中你可以去:
class SessionsController < Devise::SessionsController
def new
super
end
def create
super
end
end
您现在可以重复注册,密码和解锁的过程。
啊,是的还有另一种更简单的方法。 您可以使用devise_scope手动创建路径( 文档 ),也称为“as”而不覆盖:
as :user do
get "sign_in", :to => "devise/sessions#new"
post "sign_in", :to => "devise/sessions#create"
...
end
得到:
sign_in GET /sign_in(.:format) {:controller=>"devise/sessions", :action=>"new"}
POST /sign_in(.:format) {:controller=>"devise/sessions", :action=>"create"}
此外,您可以通过创建初始化程序来覆盖负责创建这些路由的Devise的一部分 (仅用于没有设计“破坏”路由的应用程序):
module ActionDispatch::Routing
extend ActionDispatch::Routing
class Mapper
protected
def devise_session(mapping, controllers) #:nodoc:
resource :session, :only => [], :controller => controllers[:sessions], :path => "" do
get :new, :path => mapping.path_names[:sign_in], :as => "new"
post :create, :path => mapping.path_names[:sign_in]
end
end
def devise_registration(mapping, controllers) #:nodoc:
path_names = {
:new => mapping.path_names[:sign_up],
:cancel => mapping.path_names[:cancel]
}
resource :registration, :only => [:new, :create, :edit, :update], :path => mapping.path_names[:registration],
:path_names => path_names, :controller => controllers[:registrations] do
get :cancel
end
end
end
end
请注意,此修补程序会删除Devise中使用的所有销毁路径(“会话”和“注册”中只有两个),并且仅针对此特定情况进行修复。
您还可以添加:除路线选项外。 为了做到这一点,你必须添加devise_for
方法( 从原始版本复制并修改以满足你的愿望)到Mapper类,这样它就会将[:except]选项成员发送到上面提到的(在代码中)私有方法..然后你应修改那些根据条件添加路线。
最快,最脏的方法是添加@scope [:except] = options [:except]然后修改私有方法,以便除hash之外(如果你决定使用细粒度路由控制,如:except => {:sessions => [:destroy]}
,从而使:skip
过时的)或数组(如果要从所有路由中删除此特定操作,例如:except => [:destroy]
)在添加路由之前进行检查。
无论如何,有很多方法可以实现您的需求。 你可以选择你认为最适合的那个。
实际上devise_for
确实支持:skip
和:only
,例如( docs ):
devise_for :user, :skip => :registration
这将跳过所有注册控制器的路由,而不是具体的路由。 然后,您可以实施所需的路线。 这似乎比在事后删除路线更干净。
更新:
另一种可能的解决方案是使用Rails的高级约束功能来完全阻止不需要的路由:
# config/routes.rb
constraints lambda {|req| req.url =~ /users/ && req.delete? ? false : true} do
devise_for :users
end
这是一篇关于使用lambdas进行路径约束的文章 。 这里解释了请求对象。 这可能是最简单的解决方案。
我找到了一个使用Devise 4.2.0和Rails 5.0.1的简单解决方案。 我认为这将适用于Rails 4,而且我不确定Devise的旧版本。
创建一个覆盖devise_*
路径助手的初始化器。 示例方法是devise_session
, devise_password
, devise_confirmation
, devise_unlock
和devise_registration
。 查看来源 。
通过为文件名提供更大的字母数字值,确保在Devise初始化程序之后加载初始化程序。
例如,Devise使用:new
, :create
和:show
actions创建:确认路由。 我只想要:create
动作。
# config/initializers/devise_harden.rb
module ActionDispatch::Routing
class Mapper
# Override devise's confirmation route setup, as we want to limit it to :create
def devise_confirmation(mapping, controllers)
resource :confirmation, only: [:create],
path: mapping.path_names[:confirmation], controller: controllers[:confirmations]
end
end
end
现在POST /auth/confirmation
是唯一POST /auth/confirmation
的路由设置。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.