提问人:lembon 提问时间:5/19/2023 更新时间:5/20/2023 访问量:109
Ruby on Rails 对所有路由响应“无路由匹配”,而 rack routes 命令按预期显示它们
Ruby on Rails responds "no route matches" for all routes while rack routes command shows them as expected
问:
情况
我绝对是 Ruby 的新手,但对 Django、Node 和其他技术有一定的经验。 我正在尝试在我的本地运行我的雇主的遗留项目,该项目实际上是在生产中运行的。我做的第一件事是将其docker化。Puma 服务器启动良好,它连接到 postgres 数据库,对根 127.0.0.1:3000 的响应正常,带有 Rails 默认欢迎页面。甚至 swagger 也会显示预期的端点,甚至 /rails/info/routes 也会完美地显示路由。此外,耙子路由显示完全相同:
user@local:~/path_to/project$ sudo docker compose exec app rake routes
Prefix Verb URI Pattern Controller#Action api/v1/users#index
POST /api/users(.:format) api/v1/users#create
api_user GET /api/users/:id(.:format) api/v1/users#show
PATCH /api/users/:id(.:format) api/v1/users#update
PUT /api/users/:id(.:format) api/v1/users#update
DELETE /api/users/:id(.:format) api/v1/users#destroy
api_auth_login POST /api/auth/login(.:format) api/v1/authentication#login
但是当我向 /api/auth/login 发出请求时,它会响应:
{
"status": 404,
"error": "Not Found",
"exception": "#<ActionController::RoutingError: No route matches [POST] \"/api/auth/login\">",
"traces": {
"Application Trace": [],
"Framework Trace": [
{
"exception_object_id": 47259696989680,
"id": 0,
"trace": "actionpack (6.0.3.7) lib/action_dispatch/middleware/debug_exceptions.rb:36:in `call'"
},
{
"exception_object_id": 47259696989680,
"id": 1,
"trace": "actionpack (6.0.3.7) lib/action_dispatch/middleware/show_exceptions.rb:33:in `call'"
},
[...]
控制器
├── controllers
│ ├── api
│ │ └── v1
│ │ ├── api_controller.rb
│ │ ├── authentication_controller.rb
│ │ ├── axes_controller.rb
│ │ ├── invites_controller.rb
│ │ ├── metrics_controller.rb
│ │ ├── organizations_controller.rb
│ │ └── users_controller.rb
│ └── application_controller.rb
authentication_controller.rb
module Api::V1
class AuthenticationController < ApiController
before_action :authorize_request, except: :login
include AuthHelper
def login
@user = User.find_by(game_id: params[:game_id], email: params[:email])
if @user&& @user.valid_password?(params[:password])
render json: generateToken(@user), status: :ok
else
render json: { error: 'unauthorized' }, status: :unauthorized
end
end
private
def login_params
params.permit(:email, :password, :game_id)
end
end
end
config/routes.rb
Rails.application.routes.draw do
mount Rswag::Ui::Engine => '/api-docs'
mount Rswag::Api::Engine => '/api-docs'
devise_for :users
# For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html
namespace :api do
scope module: :v1, constraints: ApiVersion.new('v1') do
resources :axes
get '/metrics', to: 'metrics#get_metrics'
get '/requests', to: 'organizations#requests'
resources :organizations
resources :invites
resources :users do
post 'forgot_password', on: :collection
post 'reset_password', on: :collection
post 'google_auth', on: :collection
get 'check_hash', on: :collection
get 'export', on: :collection
end
post '/auth/login', to: 'authentication#login'
post '/addmember', to: 'users#addUserOrganization'
get '/*a', to: 'application#not_found'
end
end
end
我不知道还能尝试什么。请帮忙!!
答:
1赞
lembon
5/19/2023
#1
我没有意识到约束,现在正在寻找 ApiVersion 类......
class ApiVersion
attr_reader :version, :default
def initialize(version, default = false)
@version = version
@default = default
end
# check whether version is specified or is default
def matches?(request)
check_headers(request.headers) || default
end
private
def check_headers(headers)
accept = headers[:accept]
accept && accept.include?("application/vnd.some_string.#{version}+json")
end
end
所以添加标题
Accept: "application/vnd.some_string.v1+json"
做到了。
评论
ApiVersion.new('v1')