406 ActionController::UnknownFormat 用户 POST [设计] [Rails API]
406 ActionController::UnknownFormat on a POST on users [Devise] [Rails API]
Rails 5.0.0.1
Ruby2.3.0p0
我正在尝试构建一个 CRUD Rails API,但我在执行 POST 时遇到了问题。我正在为用户 management 使用 devise gem。我在这里遗漏了什么吗?
当我尝试创建 POST thorugh Postman 时,我收到以下响应
{
"status": 406,
"error": "Not Acceptable",
"exception": "#<ActionController::UnknownFormat: ActionController::UnknownFormat>",
"traces": {
"Application Trace": [],
"Framework Trace": [
{
"id": 0,
"trace": "responders (2.3.0) lib/action_controller/respond_with.rb:207:in `respond_with'"
},
{
"id": 1,
"trace": "devise (4.2.0) app/controllers/devise/registrations_controller.rb:32:in `create'"
},
{
"id": 2,
"trace": "actionpack (5.0.0.1) lib/action_controller/metal/basic_implicit_render.rb:4:in `send_action'"
},
{
"id": 3,
"trace": "actionpack (5.0.0.1) lib/abstract_controller/base.rb:188:in `process_action'"
},
.....
}
日志看起来像这样
Started POST "/users/" for 127.0.0.1 at 2016-10-19 02:37:15 -0400
Processing by Devise::RegistrationsController#create as JSON
Parameters: {"email"=>"gabanimillin@gmail.com", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]"}
(0.1ms) begin transaction
(0.0ms) rollback transaction
Completed 406 Not Acceptable in 2ms (ActiveRecord: 0.1ms)
ActionController::UnknownFormat (ActionController::UnknownFormat):
responders (2.3.0) lib/action_controller/respond_with.rb:207:in `respond_with'
devise (4.2.0) app/controllers/devise/registrations_controller.rb:32:in `create'
actionpack (5.0.0.1) lib/action_controller/metal/basic_implicit_render.rb:4:in `send_action'
actionpack (5.0.0.1) lib/abstract_controller/base.rb:188:in `process_action'
actionpack (5.0.0.1) lib/action_controller/metal/rendering.rb:30:in `process_action'
actionpack (5.0.0.1) lib/abstract_controller/callbacks.rb:20:in `block in process_action'
.....
据我所知,我在 user_controller 中的代码应该可以工作
app/controllers/api/v1/user_controller.rb
class Api::V1::UsersController < ApplicationController
respond_to :json
def show
respond_with User.find(params[:id])
end
def create
user = User.new(user_params)
if user.save
render json: user, status: 201, location: [:api, user]
else
render json: { errors: user.errors }, status: 422
end
end
private
def user_params
params.require(:user).permit(:email, :password, :password_confirmation)
end
end
config/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, :create]
end
end
end
我的规格文件看起来像
spec/controllers/api/v1
require 'rails_helper'
RSpec.describe Api::V1::UsersController, type: :controller do
before(:each) { request.headers['Accept'] = "application/vnd.traveltime_test.v1"}
describe "GET #show" do
before(:each) do
@user = FactoryGirl.create :user
get :show, params: {id: @user.id}, format: :json
end
it "returns the information about a reporter on a hash" do
user_response = JSON.parse(response.body, symbolize_names: true)
expect(user_response[:email]).to eql @user.email
end
it "respond is successful" do
expect(response.status).to eql 200
end
end
describe "POST #create" do
before(:each) do
@user_attributes = FactoryGirl.create :user
post :create, {user: @user_attributes}, format: :json
end
it "returns json body for the user just created" do
end
end
end
这是我 运行 测试后得到的
F
Failures:
1) Api::V1::UsersController POST #create returns json body for the user just created
Failure/Error: params.require(:user).permit(:email, :password, :password_confirmation)
NoMethodError:
undefined method `permit' for "1":String
Did you mean? print
# ./app/controllers/api/v1/users_controller.rb:19:in `user_params'
# ./app/controllers/api/v1/users_controller.rb:8:in `create'
# /Users/GabBook/.rvm/gems/ruby-2.3.0/gems/devise-4.2.0/lib/devise/test/controller_helpers.rb:33:in `block in process'
# /Users/GabBook/.rvm/gems/ruby-2.3.0/gems/devise-4.2.0/lib/devise/test/controller_helpers.rb:100:in `catch'
# /Users/GabBook/.rvm/gems/ruby-2.3.0/gems/devise-4.2.0/lib/devise/test/controller_helpers.rb:100:in `_catch_warden'
# /Users/GabBook/.rvm/gems/ruby-2.3.0/gems/devise-4.2.0/lib/devise/test/controller_helpers.rb:33:in `process'
# ./spec/controllers/api/v1/users_controller_spec.rb:25:in `block (3 levels) in <top (required)>'
Finished in 0.05922 seconds (files took 1.18 seconds to load)
3 examples, 1 failure
Failed examples:
rspec ./spec/controllers/api/v1/users_controller_spec.rb:28 # Api::V1::UsersController POST #create returns json body for the user just created
问题出在您的 POSTMAN 参数上。
您发布了:
{ "email" => "email", "password" => "password }
而您的控制器需要以下参数:
{ "user" => { "email" => "email", "password" => "password" } }
如您的参数消毒剂所述:
params.require(:user).permit(:email, :password, :password_confirmation)
改变它
before(:each) do
@user_attributes = FactoryGirl.create :user
post :create, {user: @user_attributes}, format: :json
end
为此
before(:each) do
@user_attributes = FactoryGirl.create :user
post :create, params: {user: @user_attributes}, format: :json
end
Rails 5.0.0.1
Ruby2.3.0p0
我正在尝试构建一个 CRUD Rails API,但我在执行 POST 时遇到了问题。我正在为用户 management 使用 devise gem。我在这里遗漏了什么吗?
当我尝试创建 POST thorugh Postman 时,我收到以下响应
{
"status": 406,
"error": "Not Acceptable",
"exception": "#<ActionController::UnknownFormat: ActionController::UnknownFormat>",
"traces": {
"Application Trace": [],
"Framework Trace": [
{
"id": 0,
"trace": "responders (2.3.0) lib/action_controller/respond_with.rb:207:in `respond_with'"
},
{
"id": 1,
"trace": "devise (4.2.0) app/controllers/devise/registrations_controller.rb:32:in `create'"
},
{
"id": 2,
"trace": "actionpack (5.0.0.1) lib/action_controller/metal/basic_implicit_render.rb:4:in `send_action'"
},
{
"id": 3,
"trace": "actionpack (5.0.0.1) lib/abstract_controller/base.rb:188:in `process_action'"
},
.....
}
日志看起来像这样
Started POST "/users/" for 127.0.0.1 at 2016-10-19 02:37:15 -0400
Processing by Devise::RegistrationsController#create as JSON
Parameters: {"email"=>"gabanimillin@gmail.com", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]"}
(0.1ms) begin transaction
(0.0ms) rollback transaction
Completed 406 Not Acceptable in 2ms (ActiveRecord: 0.1ms)
ActionController::UnknownFormat (ActionController::UnknownFormat):
responders (2.3.0) lib/action_controller/respond_with.rb:207:in `respond_with'
devise (4.2.0) app/controllers/devise/registrations_controller.rb:32:in `create'
actionpack (5.0.0.1) lib/action_controller/metal/basic_implicit_render.rb:4:in `send_action'
actionpack (5.0.0.1) lib/abstract_controller/base.rb:188:in `process_action'
actionpack (5.0.0.1) lib/action_controller/metal/rendering.rb:30:in `process_action'
actionpack (5.0.0.1) lib/abstract_controller/callbacks.rb:20:in `block in process_action'
.....
据我所知,我在 user_controller 中的代码应该可以工作
app/controllers/api/v1/user_controller.rb
class Api::V1::UsersController < ApplicationController
respond_to :json
def show
respond_with User.find(params[:id])
end
def create
user = User.new(user_params)
if user.save
render json: user, status: 201, location: [:api, user]
else
render json: { errors: user.errors }, status: 422
end
end
private
def user_params
params.require(:user).permit(:email, :password, :password_confirmation)
end
end
config/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, :create]
end
end
end
我的规格文件看起来像
spec/controllers/api/v1
require 'rails_helper'
RSpec.describe Api::V1::UsersController, type: :controller do
before(:each) { request.headers['Accept'] = "application/vnd.traveltime_test.v1"}
describe "GET #show" do
before(:each) do
@user = FactoryGirl.create :user
get :show, params: {id: @user.id}, format: :json
end
it "returns the information about a reporter on a hash" do
user_response = JSON.parse(response.body, symbolize_names: true)
expect(user_response[:email]).to eql @user.email
end
it "respond is successful" do
expect(response.status).to eql 200
end
end
describe "POST #create" do
before(:each) do
@user_attributes = FactoryGirl.create :user
post :create, {user: @user_attributes}, format: :json
end
it "returns json body for the user just created" do
end
end
end
这是我 运行 测试后得到的
F
Failures:
1) Api::V1::UsersController POST #create returns json body for the user just created
Failure/Error: params.require(:user).permit(:email, :password, :password_confirmation)
NoMethodError:
undefined method `permit' for "1":String
Did you mean? print
# ./app/controllers/api/v1/users_controller.rb:19:in `user_params'
# ./app/controllers/api/v1/users_controller.rb:8:in `create'
# /Users/GabBook/.rvm/gems/ruby-2.3.0/gems/devise-4.2.0/lib/devise/test/controller_helpers.rb:33:in `block in process'
# /Users/GabBook/.rvm/gems/ruby-2.3.0/gems/devise-4.2.0/lib/devise/test/controller_helpers.rb:100:in `catch'
# /Users/GabBook/.rvm/gems/ruby-2.3.0/gems/devise-4.2.0/lib/devise/test/controller_helpers.rb:100:in `_catch_warden'
# /Users/GabBook/.rvm/gems/ruby-2.3.0/gems/devise-4.2.0/lib/devise/test/controller_helpers.rb:33:in `process'
# ./spec/controllers/api/v1/users_controller_spec.rb:25:in `block (3 levels) in <top (required)>'
Finished in 0.05922 seconds (files took 1.18 seconds to load)
3 examples, 1 failure
Failed examples:
rspec ./spec/controllers/api/v1/users_controller_spec.rb:28 # Api::V1::UsersController POST #create returns json body for the user just created
问题出在您的 POSTMAN 参数上。 您发布了:
{ "email" => "email", "password" => "password }
而您的控制器需要以下参数:
{ "user" => { "email" => "email", "password" => "password" } }
如您的参数消毒剂所述:
params.require(:user).permit(:email, :password, :password_confirmation)
改变它
before(:each) do
@user_attributes = FactoryGirl.create :user
post :create, {user: @user_attributes}, format: :json
end
为此
before(:each) do
@user_attributes = FactoryGirl.create :user
post :create, params: {user: @user_attributes}, format: :json
end