【问题标题】:Rails 3 routing - :delete method on :collectionRails 3 路由 - :collection 上的 :delete 方法
【发布时间】:2011-05-24 18:54:29
【问题描述】:

我想创建一个允许删除所有shares 的路由。 RESTful 方式是使用动词DELETE。如何创建指向:

DELETE /shares

我尝试过路线:

resources :shares do
  delete :on => :collection
end

但这产生了一个错误,即 rails 无法将 nil 转换为符号。

现在我有:

resources :shares do
  delete 'delete_all', :on => :collection
end

编辑:我在控制器操作名称中有错字,后一种方式有效,但生成的 URL /shares/delete_all 不是很 RESTful。

如何删除 _delete_all_ 部分?

【问题讨论】:

    标签: ruby-on-rails-3 routing


    【解决方案1】:

    对于 Rails 3,您可以这样做,并拥有很好的资源丰富的 GET/DELETE 收集操作,分别指向 index 和 delete_all:

    resources :shares do
      delete :index, on: :collection, action: :delete_all
    end
    

    如果您使用的是 Rails 4,您可以使用关注点来干燥它并将其应用于许多资源:

    concern :deleteallable do
      delete :index, on: :collection, action: :delete_all
    end
    
    resources :shares, concerns: :deleteallable
    resources :widgets, concerns: :deleteallable
    

    【讨论】:

      【解决方案2】:

      我错过了什么?

      match 'shares', :to => 'shares#delete_all', :via => :delete
      

      更多信息:http://www.engineyard.com/blog/2010/the-lowdown-on-routes-in-rails-3/

      <subjective opinion> 这通常是一个坏主意和代码/设计气味。通过 RESTful 接口删除所有记录的需求实际上应该在受保护(经过身份验证)的操作之后,并且/或者该操作应该以某种方式限定给用户。

      【讨论】:

      • 他的问题或您的回答中没有任何内容表明所有共享的删除方法不需要身份验证,或者不需要授权。在实际执行您要求的操作之前,您永远无法仅从路由中判断操作是否检查了正确的授权。
      • 这就是为什么我试图让他抬起头来避免未来的挫败感。
      • 这当然行得通!我不知何故在resource 盒子里思考,忘记了match。顺便说一句,我们正在使用适当的授权,无论如何这都是为了开发,准备好后可能会从生产中删除。
      • 是的,对不起,如果我的subjective opinion 看起来很苛刻。出于开发目的,这是一个在野外发现的小动作——戴上防火手套:)
      【解决方案3】:

      在路线中适合您的情况:

      resources :shares, except: :destroy
      resource :share, only: :destroy
      

      请注意,我写了 resource 这个词来表示销毁操作

      然后在shares_controller中重新定义“destroy”:

        def destroy
          respond_to do |format|
            if Share.destroy_all
              format.html { redirect_to root_path, notice: 'Share collection successfully deleted' }
            else
              format.html { redirect_to root_path, notice: 'Share collection cannot be deleted.' }
            end
          end
        end
      

      【讨论】:

        【解决方案4】:

        这是非 REST 的做法:

        resources :shares do
            collection do
                delete :destroy_all
            end
        end
        

        然后在你的控制器中你将需要这样的东西:

        def destroy_all
            Share.delete_all
        end
        

        那么这就是你想要做的:

        resources :shares do
            collection do
                delete :index
            end
        end
        

        然后在你的控制器中你将需要这样的东西:

        def index
           if request.method == delete #delete might need to be a string here, I don't know
            Share.delete_all
           else
             @shares = Share.all    
           end 
        end
        

        【讨论】:

          【解决方案5】:

          至少在 Rails 4.2 中有一个稍微简单的语法:

          resources :shares do
            delete on: :collection, action: :destroy_all
          end
          

          【讨论】:

            【解决方案6】:
            resources :shares do
                collection do
                    delete '/', :to => :delete_all
                end
            end
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多