kurenn / market_place_api

The API on Rails tutorial application
142 stars 70 forks source link

chapter 3: ActionController::UnknownFormat in Devise::RegistrationsController#create #8

Open luxxi opened 9 years ago

luxxi commented 9 years ago

I finished Chapter 3. GET, PATCH and DELETE are working, but on POST request I get ActionController::UnknownFormat (ActionController::UnknownFormat)

Started POST "/users" for 127.0.0.1 at 2015-03-17 21:29:39 +0100
Processing by Devise::RegistrationsController#create as application/vnd.marketplace.v1
  Parameters: {"user"=>{"email"=>"test6@test.si", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]"}, "registration"=>{"user"=>{"email"=>"test6@test.si", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]"}}}
Can't verify CSRF token authenticity
   (0.3ms)  BEGIN
  User Exists (0.7ms)  SELECT  1 AS one FROM "users" WHERE "users"."email" = 'test6@test.si' LIMIT 1
  SQL (0.4ms)  INSERT INTO "users" ("email", "encrypted_password", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "id"  [["email", "test6@test.si"], ["encrypted_password", "$2a$10$3YXrXSF423U.ztCVY.hP.uCHb11QJSDqDlm0.WTX.427BIVUnhvw2"], ["created_at", "2015-03-17 20:29:40.052900"], ["updated_at", "2015-03-17 20:29:40.052900"]]
   (2.0ms)  COMMIT
   (0.3ms)  BEGIN
  SQL (0.3ms)  UPDATE "users" SET "last_sign_in_at" = $1, "current_sign_in_at" = $2, "last_sign_in_ip" = $3, "current_sign_in_ip" = $4, "sign_in_count" = $5, "updated_at" = $6 WHERE "users"."id" = $7  [["last_sign_in_at", "2015-03-17 20:29:40.057666"], ["current_sign_in_at", "2015-03-17 20:29:40.057666"], ["last_sign_in_ip", "127.0.0.1/32"], ["current_sign_in_ip", "127.0.0.1/32"], ["sign_in_count", 1], ["updated_at", "2015-03-17 20:29:40.059548"], ["id", 8]]
   (0.4ms)  COMMIT
Completed 406 Not Acceptable in 98ms

ActionController::UnknownFormat (ActionController::UnknownFormat):
  responders (2.1.0) lib/action_controller/respond_with.rb:205:in `respond_with'
  devise (3.4.1) app/controllers/devise/registrations_controller.rb:25:in `create'
  actionpack (4.2.0) lib/action_controller/metal/implicit_render.rb:4:in `send_action'
  actionpack (4.2.0) lib/abstract_controller/base.rb:198:in `process_action'
  actionpack (4.2.0) lib/action_controller/metal/rendering.rb:10:in `process_action'
  actionpack (4.2.0) lib/abstract_controller/callbacks.rb:20:in `block in process_action'
  activesupport (4.2.0) lib/active_support/callbacks.rb:117:in `call'
  activesupport (4.2.0) lib/active_support/callbacks.rb:117:in `call'
  activesupport (4.2.0) lib/active_support/callbacks.rb:234:in `block in halting'
  activesupport (4.2.0) lib/active_support/callbacks.rb:169:in `call'
  activesupport (4.2.0) lib/active_support/callbacks.rb:169:in `block in halting'
  activesupport (4.2.0) lib/active_support/callbacks.rb:169:in `call'
  activesupport (4.2.0) lib/active_support/callbacks.rb:169:in `block in halting'
  activesupport (4.2.0) lib/active_support/callbacks.rb:151:in `call'
  activesupport (4.2.0) lib/active_support/callbacks.rb:151:in `block in halting_and_conditional'
  activesupport (4.2.0) lib/active_support/callbacks.rb:151:in `call'
  activesupport (4.2.0) lib/active_support/callbacks.rb:151:in `block in halting_and_conditional'
  activesupport (4.2.0) lib/active_support/callbacks.rb:92:in `call'
  activesupport (4.2.0) lib/active_support/callbacks.rb:92:in `_run_callbacks'
  activesupport (4.2.0) lib/active_support/callbacks.rb:734:in `_run_process_action_callbacks'
  activesupport (4.2.0) lib/active_support/callbacks.rb:81:in `run_callbacks'
  actionpack (4.2.0) lib/abstract_controller/callbacks.rb:19:in `process_action'
  actionpack (4.2.0) lib/action_controller/metal/rescue.rb:29:in `process_action'
  actionpack (4.2.0) lib/action_controller/metal/instrumentation.rb:31:in `block in process_action'
  activesupport (4.2.0) lib/active_support/notifications.rb:164:in `block in instrument'
  activesupport (4.2.0) lib/active_support/notifications/instrumenter.rb:20:in `instrument'
  activesupport (4.2.0) lib/active_support/notifications.rb:164:in `instrument'
  actionpack (4.2.0) lib/action_controller/metal/instrumentation.rb:30:in `process_action'
  actionpack (4.2.0) lib/action_controller/metal/params_wrapper.rb:250:in `process_action'
  activerecord (4.2.0) lib/active_record/railties/controller_runtime.rb:18:in `process_action'
  actionpack (4.2.0) lib/abstract_controller/base.rb:137:in `process'
  actionview (4.2.0) lib/action_view/rendering.rb:30:in `process'
  actionpack (4.2.0) lib/action_controller/metal.rb:195:in `dispatch'
  actionpack (4.2.0) lib/action_controller/metal/rack_delegation.rb:13:in `dispatch'
  actionpack (4.2.0) lib/action_controller/metal.rb:236:in `block in action'
  actionpack (4.2.0) lib/action_dispatch/routing/route_set.rb:73:in `call'
  actionpack (4.2.0) lib/action_dispatch/routing/route_set.rb:73:in `dispatch'
  actionpack (4.2.0) lib/action_dispatch/routing/route_set.rb:42:in `serve'
  actionpack (4.2.0) lib/action_dispatch/routing/mapper.rb:49:in `serve'
  actionpack (4.2.0) lib/action_dispatch/journey/router.rb:43:in `block in serve'
  actionpack (4.2.0) lib/action_dispatch/journey/router.rb:30:in `each'
  actionpack (4.2.0) lib/action_dispatch/journey/router.rb:30:in `serve'
  actionpack (4.2.0) lib/action_dispatch/routing/route_set.rb:802:in `call'
  warden (1.2.3) lib/warden/manager.rb:35:in `block in call'
  warden (1.2.3) lib/warden/manager.rb:34:in `catch'
  warden (1.2.3) lib/warden/manager.rb:34:in `call'
  rack (1.6.0) lib/rack/etag.rb:24:in `call'
  rack (1.6.0) lib/rack/conditionalget.rb:38:in `call'
  rack (1.6.0) lib/rack/head.rb:13:in `call'
  actionpack (4.2.0) lib/action_dispatch/middleware/params_parser.rb:27:in `call'
  actionpack (4.2.0) lib/action_dispatch/middleware/flash.rb:260:in `call'
  rack (1.6.0) lib/rack/session/abstract/id.rb:225:in `context'
  rack (1.6.0) lib/rack/session/abstract/id.rb:220:in `call'
  actionpack (4.2.0) lib/action_dispatch/middleware/cookies.rb:560:in `call'
  activerecord (4.2.0) lib/active_record/query_cache.rb:36:in `call'
  activerecord (4.2.0) lib/active_record/connection_adapters/abstract/connection_pool.rb:647:in `call'
  activerecord (4.2.0) lib/active_record/migration.rb:378:in `call'
  actionpack (4.2.0) lib/action_dispatch/middleware/callbacks.rb:29:in `block in call'
  activesupport (4.2.0) lib/active_support/callbacks.rb:88:in `call'
  activesupport (4.2.0) lib/active_support/callbacks.rb:88:in `_run_callbacks'
  activesupport (4.2.0) lib/active_support/callbacks.rb:734:in `_run_call_callbacks'
  activesupport (4.2.0) lib/active_support/callbacks.rb:81:in `run_callbacks'
  actionpack (4.2.0) lib/action_dispatch/middleware/callbacks.rb:27:in `call'
  actionpack (4.2.0) lib/action_dispatch/middleware/reloader.rb:73:in `call'
  actionpack (4.2.0) lib/action_dispatch/middleware/remote_ip.rb:78:in `call'
  actionpack (4.2.0) lib/action_dispatch/middleware/debug_exceptions.rb:17:in `call'
  web-console (2.1.2) lib/web_console/middleware.rb:37:in `call'
  actionpack (4.2.0) lib/action_dispatch/middleware/show_exceptions.rb:30:in `call'
  railties (4.2.0) lib/rails/rack/logger.rb:38:in `call_app'
  railties (4.2.0) lib/rails/rack/logger.rb:20:in `block in call'
  activesupport (4.2.0) lib/active_support/tagged_logging.rb:68:in `block in tagged'
  activesupport (4.2.0) lib/active_support/tagged_logging.rb:26:in `tagged'
  activesupport (4.2.0) lib/active_support/tagged_logging.rb:68:in `tagged'
  railties (4.2.0) lib/rails/rack/logger.rb:20:in `call'
  actionpack (4.2.0) lib/action_dispatch/middleware/request_id.rb:21:in `call'
  rack (1.6.0) lib/rack/methodoverride.rb:22:in `call'
  rack (1.6.0) lib/rack/runtime.rb:18:in `call'
  activesupport (4.2.0) lib/active_support/cache/strategy/local_cache_middleware.rb:28:in `call'
  rack (1.6.0) lib/rack/lock.rb:17:in `call'
  actionpack (4.2.0) lib/action_dispatch/middleware/static.rb:113:in `call'
  rack (1.6.0) lib/rack/sendfile.rb:113:in `call'
  railties (4.2.0) lib/rails/engine.rb:518:in `call'
  railties (4.2.0) lib/rails/application.rb:164:in `call'
  /Users/luka/Library/Application Support/Pow/Versions/0.5.0/node_modules/nack/lib/nack/server.rb:155:in `handle'
  /Users/luka/Library/Application Support/Pow/Versions/0.5.0/node_modules/nack/lib/nack/server.rb:109:in `rescue in block (2 levels) in start'
  /Users/luka/Library/Application Support/Pow/Versions/0.5.0/node_modules/nack/lib/nack/server.rb:106:in `block (2 levels) in start'
  /Users/luka/Library/Application Support/Pow/Versions/0.5.0/node_modules/nack/lib/nack/server.rb:96:in `each'
  /Users/luka/Library/Application Support/Pow/Versions/0.5.0/node_modules/nack/lib/nack/server.rb:96:in `block in start'
  /Users/luka/Library/Application Support/Pow/Versions/0.5.0/node_modules/nack/lib/nack/server.rb:76:in `loop'
  /Users/luka/Library/Application Support/Pow/Versions/0.5.0/node_modules/nack/lib/nack/server.rb:76:in `start'
  /Users/luka/Library/Application Support/Pow/Versions/0.5.0/node_modules/nack/lib/nack/server.rb:12:in `run'
  /Users/luka/Library/Application Support/Pow/Versions/0.5.0/node_modules/nack/bin/nack_worker:4:in `<main>'

  Rendered /usr/local/var/rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/actionpack-4.2.0/lib/action_dispatch/middleware/templates/rescues/_source.erb (5.7ms)
  Rendered /usr/local/var/rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/actionpack-4.2.0/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb (2.7ms)
  Rendered /usr/local/var/rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/actionpack-4.2.0/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb (1.0ms)
  Rendered /usr/local/var/rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/actionpack-4.2.0/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb within rescues/layout (68.8ms)
Cannot render console with content type application/jsonAllowed content types: [#<Mime::Type:0x007fd8c51f6d78 @synonyms=["application/xhtml+xml"], @symbol=:html, @string="text/html">, #<Mime::Type:0x007fd8c51f68c8 @synonyms=[], @symbol=:text, @string="text/plain">, #<Mime::Type:0x007fd8c51ecc88 @synonyms=[], @symbol=:url_encoded_form, @string="application/x-www-form-urlencoded">]
kurenn commented 9 years ago

The devise_for :users line is not inside the api namespace, if you want to use the devise controllers, you might need to override the response format

pavel-clarityhk commented 9 years ago

@kurenn , have you tried sending actual requests to the app with curl or Postman?

Looking at rake routes, we can see that there is actually two same routes for POST /users:

user_registration POST   /users(.:format)                       devise/registrations#create
api_users POST   /users(.:format)                       api/v1/users#create {:format=>:json, :subdomain=>"api"}

So when you run tests, you explicitly call the #create method of the UsersController, but when you send a real request, it actually routes to devise/registrations#create. It looks like like this is the problem @luxxi is having.

If I understood correctly, we still need the Devise routes, since without them the sign_in method doesn't work. I managed to mitigate it by setting devise_for :users after the :api namespace in the routes.rb file, but it seems to me that there's a larger problem here that needs addressing. Or am I missing something?

kurenn commented 9 years ago

@pavel-clarityhk You are totally right, I missed that! sorry about that.

That is actually a good solution, just to first call the :api namespace and then devise_for :users

I'll be updating the book with these and many other fixes.

Thanks!

oeddyo commented 9 years ago

@kurenn Also seeing this. Would love to see the updates! I'm building a production backend following your tutorial

oeddyo commented 9 years ago
class Api::V1::RegistrationsController < Devise::RegistrationsController
  respond_to :json

  def create
    print 'in here'
    retailer = Retailer.new(retailers_params)
    if retailer.save
      render json: retailer, status: 201, location: [:api, retailer]
    else
      render json: {errors: retailer.errors}, status: 422
    end
  end

  private
  def retailers_params
    params.require(:retailer).permit(:user_name, :password, :password_confirmation)
  end
end
require 'api_constraints'

CaoWuApi::Application.routes.draw do
  mount SabisuRails::Engine => "/sabisu_rails"

  namespace :api, defaults: {format: :json}, constraints: {subdomain: 'api'}, path: '/' do
    scope module: :v1,
          constraints: ApiConstraints.new(version: 1, default: true) do

      devise_for :retailers,  :controller => {:registrations => 'registrations'}
      resources :retailers, :only => [:show] do
        resources :products, :only => [:create, :index, :show]
      end

      resources :sessions, :only => [:create, :destroy]

    end
  end

  # https://github.com/kurenn/market_place_api/issues/8
end
oeddyo commented 9 years ago

btw: Retailer = User in this context

kurenn commented 9 years ago

@luxxi were you able to solve it?

Nosfheratu commented 8 years ago

@kurenn Moved devise_for :users next to api definition solves my issue, I just want to understand why, or any simple explanation, can you?

kurenn commented 8 years ago

What do you mean by next to api definition?

Nosfheratu commented 8 years ago

I mean, in the routes, after the api namespace definition, that what I wanted to say...

kurenn commented 8 years ago

Oh yeah, it is because the /users path should be handle by the api and not by devise. The routes file matches the first route when the server is asked to serve.

So in this case you first serve with the API instead of the devise generated routes.

rigelstpierre commented 7 years ago

I was having a similar problem to this and solved it by skipping the devise registrations route.

devise_for :users, skip: :registrations