尽管路由已声明,但使用Rails 5(API标志)并且不会出现路由错误

这是我的控制器:

class Api::V1::UsersController < ApplicationController respond_to :json def show respond_with User.find(params[:id]) end end 

这是我的routes.rb

 require 'api_constraints' Rails.application.routes.draw do devise_for :users # Api definition namespace :api, defaults: { format: :json }, constraints: { subdomain: 'api' }, path: '/' do scope module: :v1, constraints: ApiConstraints.new(version: 1, default: true) do resources :users, :only => [:show] end end end 

这是我的lib/api_constraints.rb

 class ApiConstraints def initialize(options) @version = options[:version] @default = options[:default] end def matches?(req) @default || req.headers['Accept'].include?("application/vnd.myapp.v#{@version}") end end 

我在我的数据库中添加了一条记录,如下所示:

 [3] pry(main)> User.all User Load (0.4ms) SELECT "users".* FROM "users" => [#] 

然而,这是我在rails控制台中遇到的错误:

 ActionController::RoutingError (No route matches [GET] "/users/1"): actionpack (5.0.0.beta3) lib/action_dispatch/middleware/debug_exceptions.rb:53:in `call' web-console (3.1.1) lib/web_console/middleware.rb:131:in `call_app' web-console (3.1.1) lib/web_console/middleware.rb:28:in `block in call' web-console (3.1.1) lib/web_console/middleware.rb:18:in `catch' web-console (3.1.1) lib/web_console/middleware.rb:18:in `call' actionpack (5.0.0.beta3) lib/action_dispatch/middleware/show_exceptions.rb:31:in `call' railties (5.0.0.beta3) lib/rails/rack/logger.rb:36:in `call_app' railties (5.0.0.beta3) lib/rails/rack/logger.rb:24:in `block in call' activesupport (5.0.0.beta3) lib/active_support/tagged_logging.rb:70:in `block in tagged' activesupport (5.0.0.beta3) lib/active_support/tagged_logging.rb:26:in `tagged' activesupport (5.0.0.beta3) lib/active_support/tagged_logging.rb:70:in `tagged' railties (5.0.0.beta3) lib/rails/rack/logger.rb:24:in `call' actionpack (5.0.0.beta3) lib/action_dispatch/middleware/request_id.rb:24:in `call' rack (2.0.0.alpha) lib/rack/runtime.rb:22:in `call' activesupport (5.0.0.beta3) lib/active_support/cache/strategy/local_cache_middleware.rb:28:in `call' actionpack (5.0.0.beta3) lib/action_dispatch/middleware/load_interlock.rb:13:in `call' actionpack (5.0.0.beta3) lib/action_dispatch/middleware/static.rb:136:in `call' rack (2.0.0.alpha) lib/rack/sendfile.rb:111:in `call' railties (5.0.0.beta3) lib/rails/engine.rb:522:in `call' puma (3.2.0) lib/puma/configuration.rb:227:in `call' puma (3.2.0) lib/puma/server.rb:561:in `handle_request' puma (3.2.0) lib/puma/server.rb:406:in `process_client' puma (3.2.0) lib/puma/server.rb:271:in `block in run' puma (3.2.0) lib/puma/thread_pool.rb:111:in `block in spawn_thread' 

这就是我在浏览器中看到的内容:

 {"status":404,"error":"Not Found","exception":"#\u003cActionController::RoutingError: No route matches [GET] \"/users/1\"\u003e","traces":{"Application Trace":[],"Framework Trace":[{"id":0,"trace":"actionpack (5.0.0.beta3) lib/action_dispatch/middleware/debug_exceptions.rb:53:in `call'"},{"id":1,"trace":"web-console (3.1.1) lib/web_console/middleware.rb:131:in `call_app'"},{"id":2,"trace":"web-console (3.1.1) lib/web_console/middleware.rb:28:in `block in call'"},{"id":3,"trace":"web-console (3.1.1) lib/web_console/middleware.rb:18:in `catch'"},{"id":4,"trace":"web-console (3.1.1) lib/web_console/middleware.rb:18:in `call'"},{"id":5,"trace":"actionpack (5.0.0.beta3) lib/action_dispatch/middleware/show_exceptions.rb:31:in `call'"},{"id":6,"trace":"railties (5.0.0.beta3) lib/rails/rack/logger.rb:36:in `call_app'"},{"id":7,"trace":"railties (5.0.0.beta3) lib/rails/rack/logger.rb:24:in `block in call'"},{"id":8,"trace":"activesupport (5.0.0.beta3) lib/active_support/tagged_logging.rb:70:in `block in tagged'"},{"id":9,"trace":"activesupport (5.0.0.beta3) lib/active_support/tagged_logging.rb:26:in `tagged'"},{"id":10,"trace":"activesupport (5.0.0.beta3) lib/active_support/tagged_logging.rb:70:in `tagged'"},{"id":11,"trace":"railties (5.0.0.beta3) lib/rails/rack/logger.rb:24:in `call'"},{"id":12,"trace":"actionpack (5.0.0.beta3) lib/action_dispatch/middleware/request_id.rb:24:in `call'"},{"id":13,"trace":"rack (2.0.0.alpha) lib/rack/runtime.rb:22:in `call'"},{"id":14,"trace":"activesupport (5.0.0.beta3) lib/active_support/cache/strategy/local_cache_middleware.rb:28:in `call'"},{"id":15,"trace":"actionpack (5.0.0.beta3) lib/action_dispatch/middleware/load_interlock.rb:13:in `call'"},{"id":16,"trace":"actionpack (5.0.0.beta3) lib/action_dispatch/middleware/static.rb:136:in `call'"},{"id":17,"trace":"rack (2.0.0.alpha) lib/rack/sendfile.rb:111:in `call'"},{"id":18,"trace":"railties (5.0.0.beta3) lib/rails/engine.rb:522:in `call'"},{"id":19,"trace":"puma (3.2.0) lib/puma/configuration.rb:227:in `call'"},{"id":20,"trace":"puma (3.2.0) lib/puma/server.rb:561:in `handle_request'"},{"id":21,"trace":"puma (3.2.0) lib/puma/server.rb:406:in `process_client'"},{"id":22,"trace":"puma (3.2.0) lib/puma/server.rb:271:in `block in run'"},{"id":23,"trace":"puma (3.2.0) lib/puma/thread_pool.rb:111:in `block in spawn_thread'"}],"Full Trace":[{"id":0,"trace":"actionpack (5.0.0.beta3) lib/action_dispatch/middleware/debug_exceptions.rb:53:in `call'"},{"id":1,"trace":"web-console (3.1.1) lib/web_console/middleware.rb:131:in `call_app'"},{"id":2,"trace":"web-console (3.1.1) lib/web_console/middleware.rb:28:in `block in call'"},{"id":3,"trace":"web-console (3.1.1) lib/web_console/middleware.rb:18:in `catch'"},{"id":4,"trace":"web-console (3.1.1) lib/web_console/middleware.rb:18:in `call'"},{"id":5,"trace":"actionpack (5.0.0.beta3) lib/action_dispatch/middleware/show_exceptions.rb:31:in `call'"},{"id":6,"trace":"railties (5.0.0.beta3) lib/rails/rack/logger.rb:36:in `call_app'"},{"id":7,"trace":"railties (5.0.0.beta3) lib/rails/rack/logger.rb:24:in `block in call'"},{"id":8,"trace":"activesupport (5.0.0.beta3) lib/active_support/tagged_logging.rb:70:in `block in tagged'"},{"id":9,"trace":"activesupport (5.0.0.beta3) lib/active_support/tagged_logging.rb:26:in `tagged'"},{"id":10,"trace":"activesupport (5.0.0.beta3) lib/active_support/tagged_logging.rb:70:in `tagged'"},{"id":11,"trace":"railties (5.0.0.beta3) lib/rails/rack/logger.rb:24:in `call'"},{"id":12,"trace":"actionpack (5.0.0.beta3) lib/action_dispatch/middleware/request_id.rb:24:in `call'"},{"id":13,"trace":"rack (2.0.0.alpha) lib/rack/runtime.rb:22:in `call'"},{"id":14,"trace":"activesupport (5.0.0.beta3) lib/active_support/cache/strategy/local_cache_middleware.rb:28:in `call'"},{"id":15,"trace":"actionpack (5.0.0.beta3) lib/action_dispatch/middleware/load_interlock.rb:13:in `call'"},{"id":16,"trace":"actionpack (5.0.0.beta3) lib/action_dispatch/middleware/static.rb:136:in `call'"},{"id":17,"trace":"rack (2.0.0.alpha) lib/rack/sendfile.rb:111:in `call'"},{"id":18,"trace":"railties (5.0.0.beta3) lib/rails/engine.rb:522:in `call'"},{"id":19,"trace":"puma (3.2.0) lib/puma/configuration.rb:227:in `call'"},{"id":20,"trace":"puma (3.2.0) lib/puma/server.rb:561:in `handle_request'"},{"id":21,"trace":"puma (3.2.0) lib/puma/server.rb:406:in `process_client'"},{"id":22,"trace":"puma (3.2.0) lib/puma/server.rb:271:in `block in run'"},{"id":23,"trace":"puma (3.2.0) lib/puma/thread_pool.rb:111:in `block in spawn_thread'"}]}} 

编辑1

这是我的rake routes

 $ rake routes [DEPRECATION] `last_comment` is deprecated. Please use `last_description` instead. [DEPRECATION] `last_comment` is deprecated. Please use `last_description` instead. [DEPRECATION] `last_comment` is deprecated. Please use `last_description` instead. Prefix Verb URI Pattern Controller#Action new_user_session GET /users/sign_in(.:format) devise/sessions#new user_session POST /users/sign_in(.:format) devise/sessions#create destroy_user_session DELETE /users/sign_out(.:format) devise/sessions#destroy user_password POST /users/password(.:format) devise/passwords#create new_user_password GET /users/password/new(.:format) devise/passwords#new edit_user_password GET /users/password/edit(.:format) devise/passwords#edit PATCH /users/password(.:format) devise/passwords#update PUT /users/password(.:format) devise/passwords#update cancel_user_registration GET /users/cancel(.:format) devise/registrations#cancel user_registration POST /users(.:format) devise/registrations#create new_user_registration GET /users/sign_up(.:format) devise/registrations#new edit_user_registration GET /users/edit(.:format) devise/registrations#edit PATCH /users(.:format) devise/registrations#update PUT /users(.:format) devise/registrations#update DELETE /users(.:format) devise/registrations#destroy api_user GET /users/:id(.:format) api/v1/users#show {:format=>:json, :subdomain=>"api"} 

编辑2

这是我的应用程序控制器:

 class ApplicationController < ActionController::API end 

编辑3

这是我实际传递的users_controller_spec.rb测试:

 require 'rails_helper' describe Api::V1::UsersController do before(:each) { request.headers['Accept'] = "application/vnd.myapp.v1" } describe "GET #show" do before(:each) do @user = FactoryGirl.create :user get :show, id: @user.id, format: :json end it "returns the information about a user on a hash" do user_response = JSON.parse(response.body, symbolize_names: true) expect(user_response[:email]).to eql @user.email end it { should respond_with 200 } end end 

这是结果:

 $ rspec spec/controllers DEPRECATION WARNING: use_transactional_fixtures= is deprecated and will be removed from Rails 5.1 (use use_transactional_tests= instead). (called from  at /myapp/spec/controllers/api/v1/users_controller_spec.rb:3) DEPRECATION WARNING: ActionController::TestCase HTTP request methods will accept only keyword arguments in future Rails versions. Examples: get :show, params: { id: 1 }, session: { user_id: 1 } process :update, method: :post, params: { id: 1 } (called from block (3 levels) in  at /myapp/spec/controllers/api/v1/users_controller_spec.rb:9) DEPRECATION WARNING: ActionController::TestCase HTTP request methods will accept only keyword arguments in future Rails versions. Examples: get :show, params: { id: 1 }, session: { user_id: 1 } process :update, method: :post, params: { id: 1 } (called from block (3 levels) in  at /myapp/spec/controllers/api/v1/users_controller_spec.rb:9) .DEPRECATION WARNING: ActionController::TestCase HTTP request methods will accept only keyword arguments in future Rails versions. Examples: get :show, params: { id: 1 }, session: { user_id: 1 } process :update, method: :post, params: { id: 1 } (called from block (3 levels) in  at /myapp/spec/controllers/api/v1/users_controller_spec.rb:9) DEPRECATION WARNING: ActionController::TestCase HTTP request methods will accept only keyword arguments in future Rails versions. Examples: get :show, params: { id: 1 }, session: { user_id: 1 } process :update, method: :post, params: { id: 1 } (called from block (3 levels) in  at /myapp/spec/controllers/api/v1/users_controller_spec.rb:9) . Finished in 0.41411 seconds (files took 3.33 seconds to load) 2 examples, 0 failures 

问题是您的路由有一个约束需要api的子域。 所以http://api.lvh.me:3000/users/1.json可以工作,但不是http:// localhost:3000 / users / 1.json或http://lvh.me:3000/users/1 .json 。

您应该更改Ajax调用以使用api子域。 您还可以通过编写请求测试(而不是控制器测试)来确认这一点,并在使用api子域时看到它获得200,否则为404。