【问题标题】:ActionController::UrlGenerationError: No route matches for custom routesActionController::UrlGenerationError: 自定义路由没有路由匹配
【发布时间】:2016-04-29 20:54:54
【问题描述】:

因此,我创建了一个小型模型/控制器来处理我的应用程序中的令牌,并带有自定义路由。但是,当我运行测试(rspec)时,我会失败

相关代码

控制器

读取令牌(在别处生成)

class TokensController < ApplicationController
  def read_token
    #do whatever this token is supposed to do (unsubscribe, confirm email, etc)
    redirect_to(root_path)
  end
end

路线

get '/ta/:uuid' => 'tokens#read_token', param: :uuid, as: 'token_action'

rake 路线产生

token_action GET    /ta/:uuid(.:format)    tokens#read_token {:param=>:uuid}

型号

包括在创建链接时显示令牌使用的是uuid,而不是id

class Token < ActiveRecord::Base
  def to_param
    uuid
  end    
end

它在开发模式下工作! :D

但是当我运行测试时……

测试

rspec 控制器测试

require 'rails_helper'

RSpec.describe TokensController, type: :controller do
  describe "#index" do
    it "test" do
      get :read_token, uuid: "12345" #12345 is obviously not real
      expect(response).to redirect_to(root_path)
    end
  end
end

错误信息

ActionController::UrlGenerationError: 
    No route matches` {:action=>"read_token", :controller=>"tokens", :uuid=>"12345"}

我尝试了什么

嗯……几乎所有东西。

  • 我尽我所能写了路线
  • 我将 :uuid 更改为 :id 认为这可能是问题所在
  • 我尝试以不同的方式指定属性,但无济于事
  • 我在 stackoverflow 上尝试了所有类似问题的解决方案

【问题讨论】:

    标签: ruby-on-rails ruby ruby-on-rails-4 rspec routing


    【解决方案1】:

    可以通过添加 use_route: :controller_name 来使其工作;

    get :index, uuid: "12345", use_route: :tokens
    

    但是我得到这个错误是令人困惑和代码异味。

    最终解决方案

    但是,更好的解决方案是使用正确的 rails 路由资源 (http://guides.rubyonrails.org/routing.html)

    resource :vendor_registration, only: [], path: '/' do
      get :read_token, on: :member, path: '/ta/:uuid'
    end
    

    它现在可以工作了;并且仍然使用相同的路径

    【讨论】:

      【解决方案2】:
      #config/routes.rb
      resources :tokens, path: "token", only: [:create] #-> POST url.com/token
      
      #app/controllers/tokens_controller.rb
      class TokensController < ApplicationController
         def create
            @token = Token.create
            redirect_to root_url if @token
         end
      end
      
      #app/models/token.rb
      class Token < ActiveRecord::Base
         has_secure_token :uuid
      end
      

      has_secure_token 通过ActiveRecord 处理UUID / 令牌生成,因此无需通过路由手动设置(巨大的安全优势)。

      --

      测试:

      require 'rails_helper'
      
      RSpec.describe TokensController, type: :controller do
        describe "#create" do
          it "has_token" do
            post :create, use_route: :tokens
            assigns(:token).should_not be_nil
            expect(response).to redirect_to(root_path)
          end
        end
      end
      

      我对测试不是很有经验(今年应该会改变);希望您能看到通过后端而不是路由设置uuid 的好处。

      【讨论】:

      • 我认为这里有些混乱。我没有设置令牌,我正在阅读它。令牌在后端设置为(当前使用SecureRandom.urlsafe_base64.to_s,但我将研究has_secure_token
      • :index 控制器只是读取令牌。上面的代码被非常精简以显示 rspec 控制器错误而不是令牌功能
      • 好吧,我误解了你的推理等。仍然不能否认你的模式不是那么好。
      • 模式是路由的编写方式还是 rspec 测试?什么是错误的模式?
      • 模式是解决方案的效率
      猜你喜欢
      • 2015-11-26
      • 1970-01-01
      • 2019-05-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多