Ruby on rails 设计路由:有没有办法从Rails.application.routes中删除路由?

Ruby on rails 设计路由:有没有办法从Rails.application.routes中删除路由?,ruby-on-rails,ruby-on-rails-3,devise,routes,Ruby On Rails,Ruby On Rails 3,Devise,Routes,design\u for创建包含要删除的删除路由的路由,并且design\u for不支持:除了或:仅选项 如何从Rails.application.routes中删除路由?在绘图块中或之后 下面是一个bug的详细信息,这就是我们需要删除路由的原因 我们正在向自定义UJS控制器操作发出删除请求 在控制器操作中,我们删除了想要删除的内容,然后执行302重定向。这是一个坏主意,后来我们通过返回一些JSON来纠正它 一些客户端在收到302后会向重定向发出一个新的删除请求,重定向将路由到design

design\u for
创建包含要删除的删除路由的路由,并且
design\u for
不支持
:除了
:仅
选项

如何从
Rails.application.routes
中删除路由?在
绘图
块中或之后


下面是一个bug的详细信息,这就是我们需要删除路由的原因

  • 我们正在向自定义UJS控制器操作发出删除请求

  • 在控制器操作中,我们删除了想要删除的内容,然后执行302重定向。这是一个坏主意,后来我们通过返回一些JSON来纠正它

  • 一些客户端在收到302后会向重定向发出一个新的删除请求,重定向将路由到designe DELETE路由!因此不小心删除了该人!哎呀。我们以为这会是一个好机会。错误的假设
这个bug已经被修复,但是我仍然想删除这个路由


以下是我最后所做的,这是赏金获胜者在引用Jose'Valim的话时提出的:

config/routes.rb
中,我在
design\u for
调用上面添加了这个,它设置了我的
其余的“人”
路由:

delete '/person', :to => 'people#destroy'
然后在我现有的
people\u controller.rb
中,我添加了一个无操作方法:

def destroy
  render :nothing => true
end

我仍然有点恼火,因为没有一种简单的方法可以从RouteSet中删除route。另外,designe控制器的
delete
路由仍然存在,但不会被调用,因为rails在
config/routes.rb
中查找第一个匹配项并返回它。

是的,有点像。您可以完全覆盖使用的设备控制器并编写自己的控制器(如果需要,可以继承设备控制器)。可以作为指导方针

编辑 为什么我会说:)

使用以下命令覆盖会话:

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
给出:

sign_in GET  /sign_in(.:format) {:controller=>"devise/sessions", :action=>"new"}
        POST /sign_in(.:format) {:controller=>"devise/sessions", :action=>"create"}
第三次编辑 此外,您还可以通过创建初始值设定项来覆盖负责创建这些路由的应用程序(仅在没有设计“销毁”路由的应用程序中使用):

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
请注意,此修复程序删除Desive中使用的所有销毁路由(在“会话”和“注册”中只有两个),并且仅针对此特定情况进行修复

此外 您还可以向管线添加:except选项。为此,您必须将
design_for
方法(并根据您的意愿进行修改)添加到Mapper类中,以便它向上述(代码中)私有方法发送[:except]选项成员。。然后,您应该修改这些条件以根据条件添加路由

最快、最肮脏的方法是添加@scope[:except]=options[:except],然后修改私有方法,以便使用except散列(如果您决定使用细粒度路由控制,如:
:except=>{:sessions=>[:destroy]}
,从而使
:skip
过时)或数组(如果要从所有路由中删除此特定操作,例如:
:except=>[:destroy]
)将在添加路由之前选中


无论如何,有很多方法可以满足你的需要。你可以选择你认为最合适的方法。

实际上
设计支持
:跳过
:仅
,例如():

这将跳过所有注册控制器的路由,而不是一个特定的路由。然后您可以实现所需的路由。这似乎比事后删除路由更干净

更新:

另一种可能的解决方案是使用Rails的功能完全阻塞不需要的路线:

# config/routes.rb
constraints lambda {|req| req.url =~ /users/ && req.delete? ? false : true} do
  devise_for :users
end
下面是一篇关于使用的帖子。对请求对象进行了解释。这可能是最简单的解决方案。

以下是Jose Valim(Deave的作者)的观点:

无法单独删除路由。或者使用:跳到 删除所有内容并手动绘制所需内容,或者覆盖此内容 通过首先在配置中定义到相同路径的路由/ routes.rb


因此,你的问题的简短答案是不,你不能删除这一条路线。你当然可以尝试做一些事情,比如修补Desive_for方法,但这将是一项有点复杂的任务(一天或几天的努力)。我只需要使用:skip选项,然后为该控制器实现您想要的路由,而不使用您不想要的路由。

我在Desive 4.2.0和Rails 5.0.1中找到了一个简单的解决方案。我认为这将适用于Rails 4,我不确定Desive的旧版本

创建覆盖路径帮助程序的初始值设定项。示例方法有
设计会话
设计密码
设计确认
设计解锁
,以及
设计注册
。请查看

通过为文件名提供较大的字母数字值,确保在设计初始值设定项之后加载初始值设定项

例如,Deviate使用
:new
:create
:show
操作创建:确认路由。我只需要
:create
操作

#config/initializers/designe_harden.rb
模块ActionDispatch::路由
类映射器
#覆盖Desive的确认路由设置,因为我们希望将其限制为:create
def设计确认(映射、控制器)
资源:确认,仅:[:创建],
路径:映射。路径\名称[:确认],控制器:控制器[:确认]
结束
结束
结束

现在,
POST/auth/confirmation
是唯一用于确认的路由设置。

问题很好。如果知道IE8的bug是什么,那就太好了!我添加了一个关于我们的bug的故事的编辑。不确定这个bug是IE8独有的,请参见302s上的回答:。对于后代,我已经附加了
devise_for :user, :skip => :registration
# config/routes.rb
constraints lambda {|req| req.url =~ /users/ && req.delete? ? false : true} do
  devise_for :users
end