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