ActionController :: UrlGenerationError:没有路由匹配自定义路由

时间:2016-01-23 06:52:40

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

所以我创建了一个小型模型/控制器来处理我的应用程序中的令牌,并使用自定义路径。但是当我运行测试(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上类似问题的每个解决方案

2 个答案:

答案 0 :(得分:4)

可以通过添加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

它现在有效;并且仍然使用相同的路径

答案 1 :(得分:-1)

#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通过UUID处理ActiveRecord /令牌生成,因此无需通过路由手动设置(大量安全优势)。

-

测试:

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而不是路由的好处。