Search code examples
ruby-on-railsmongodbactiveresource

ActiveResource post raises an error, while doing the post in my browser succeeds


I have a very strange problem which I am not able to tackle. Two Rails apps, one is an API that has an entity Mongo::Enrollment, and the other one is a client that has the entity Enrollment connected to the API with ActiveResource.

I defined my /app/models/enrollment.rb on the client with ActiveResource, and in the controller I am making a call like this:

enrollment = Enrollment.post(:create, enrollment: {
        :enrollment_type => :test,
        :enrollment_information => {test: 'test information'}
})

I know I can use .new and .save here too as it is ActiveResource, but it is giving me the same results.

When I actually post this, I get the following error in my log:

RuntimeError (Circular dependency detected while autoloading constant Enrollment)

But if I copy the URL from my log, paste it in Postman using the same Basic auth, accept header and POST method, I get no error at all and it saves the enrollment into mongodb.

I really hope someone can help me. I think it's very strange that what seems to be the exact same HTTP request, fetches different results. I have tried restarting both apps, and doing the request in different manners from the client, but every time I make the request from the client it's giving me the error above. The controller and the model on the API side seem to be fine, I also have an HTML interface on the API app and that's working perfectly.

This is what I have in my API app:

It is defined in routes simple as:

resources :enrollments

In the EnrollmentsController I have

# /app/controllers/enrollments_controller.rb
class EnrollmentsController < ApplicationController
  ...
  def create

    @enrollment = Mongo::Enrollment.new(enrollment_parameters)

    respond_to do |format|
      if @enrollment.save
        format.html { redirect_to @enrollment, notice: 'Note was successfully created.' }
        format.json { render json: @enrollment }
      else
        format.html { render action: 'new' }
        format.json { render json: @enrollment.errors, status: :unprocessable_entity }
      end
    end

  end
  ...
end

This is my model:

# /app/models/mongo/enrollment.rb
module Mongo
  class Enrollment
    include Mongoid::Document
    include Mongoid::Timestamps
    include Mongoid::Paranoia

    default_scope ->{ where(processed: false)}

    field :processed, :type => Boolean, :default => false
    field :accepted, :type => Boolean, :default => false

    field :enrollment_type

    field :enrollment_information, :type => Hash, :default => {}
  end
end

Full stack trace:

Started POST "/api/v1.0/enrollments/create.json?enrollment..." for 127.0.0.1 at 2014-08-31 10:12:33 -0400

RuntimeError (Circular dependency detected while autoloading constant Enrollment):
  vendor/bundle/ruby/2.1.0/gems/activesupport-4.0.2/lib/active_support/dependencies.rb:461:in `load_missing_constant'
  vendor/bundle/ruby/2.1.0/gems/activesupport-4.0.2/lib/active_support/dependencies.rb:184:in `const_missing'
  vendor/bundle/ruby/2.1.0/gems/activesupport-4.0.2/lib/active_support/inflector/methods.rb:226:in `const_get'
  vendor/bundle/ruby/2.1.0/gems/activesupport-4.0.2/lib/active_support/inflector/methods.rb:226:in `block in constantize'
  vendor/bundle/ruby/2.1.0/gems/activesupport-4.0.2/lib/active_support/inflector/methods.rb:224:in `each'
  vendor/bundle/ruby/2.1.0/gems/activesupport-4.0.2/lib/active_support/inflector/methods.rb:224:in `inject'
  vendor/bundle/ruby/2.1.0/gems/activesupport-4.0.2/lib/active_support/inflector/methods.rb:224:in `constantize'
  vendor/bundle/ruby/2.1.0/gems/activesupport-4.0.2/lib/active_support/inflector/methods.rb:269:in `safe_constantize'
  vendor/bundle/ruby/2.1.0/gems/activesupport-4.0.2/lib/active_support/core_ext/string/inflections.rb:77:in `safe_constantize'
  vendor/bundle/ruby/2.1.0/gems/actionpack-4.0.2/lib/action_controller/metal/params_wrapper.rb:145:in `_default_wrap_model'
  vendor/bundle/ruby/2.1.0/gems/actionpack-4.0.2/lib/action_controller/metal/params_wrapper.rb:96:in `block in model'
  /usr/local/rvm/rubies/ruby-2.1.1/lib/ruby/2.1.0/mutex_m.rb:73:in `synchronize'
  /usr/local/rvm/rubies/ruby-2.1.1/lib/ruby/2.1.0/mutex_m.rb:73:in `mu_synchronize'
  vendor/bundle/ruby/2.1.0/gems/actionpack-4.0.2/lib/action_controller/metal/params_wrapper.rb:96:in `model'
  vendor/bundle/ruby/2.1.0/gems/actionpack-4.0.2/lib/action_controller/metal/params_wrapper.rb:119:in `name'
  vendor/bundle/ruby/2.1.0/gems/actionpack-4.0.2/lib/action_controller/metal/params_wrapper.rb:252:in `_wrapper_key'
  vendor/bundle/ruby/2.1.0/gems/actionpack-4.0.2/lib/action_controller/metal/params_wrapper.rb:275:in `_wrapper_enabled?'
  vendor/bundle/ruby/2.1.0/gems/actionpack-4.0.2/lib/action_controller/metal/params_wrapper.rb:233:in `process_action'
  vendor/bundle/ruby/2.1.0/gems/activerecord-4.0.2/lib/active_record/railties/controller_runtime.rb:18:in `process_action'
  vendor/bundle/ruby/2.1.0/gems/actionpack-4.0.2/lib/abstract_controller/base.rb:136:in `process'
  vendor/bundle/ruby/2.1.0/gems/actionpack-4.0.2/lib/abstract_controller/rendering.rb:44:in `process'
  vendor/bundle/ruby/2.1.0/gems/actionpack-4.0.2/lib/action_controller/metal.rb:195:in `dispatch'
  vendor/bundle/ruby/2.1.0/gems/actionpack-4.0.2/lib/action_controller/metal/rack_delegation.rb:13:in `dispatch'
  vendor/bundle/ruby/2.1.0/gems/actionpack-4.0.2/lib/action_controller/metal.rb:231:in `block in action'
  vendor/bundle/ruby/2.1.0/gems/actionpack-4.0.2/lib/action_dispatch/routing/route_set.rb:80:in `call'
  vendor/bundle/ruby/2.1.0/gems/actionpack-4.0.2/lib/action_dispatch/routing/route_set.rb:80:in `dispatch'
  vendor/bundle/ruby/2.1.0/gems/actionpack-4.0.2/lib/action_dispatch/routing/route_set.rb:48:in `call'
  vendor/bundle/ruby/2.1.0/gems/actionpack-4.0.2/lib/action_dispatch/journey/router.rb:71:in `block in call'
  vendor/bundle/ruby/2.1.0/gems/actionpack-4.0.2/lib/action_dispatch/journey/router.rb:59:in `each'
  vendor/bundle/ruby/2.1.0/gems/actionpack-4.0.2/lib/action_dispatch/journey/router.rb:59:in `call'
  vendor/bundle/ruby/2.1.0/gems/actionpack-4.0.2/lib/action_dispatch/routing/route_set.rb:680:in `call'
  vendor/bundle/ruby/2.1.0/gems/warden-1.2.3/lib/warden/manager.rb:35:in `block in call'
  vendor/bundle/ruby/2.1.0/gems/warden-1.2.3/lib/warden/manager.rb:34:in `catch'
  vendor/bundle/ruby/2.1.0/gems/warden-1.2.3/lib/warden/manager.rb:34:in `call'
  vendor/bundle/ruby/2.1.0/gems/rack-1.5.2/lib/rack/etag.rb:23:in `call'
  vendor/bundle/ruby/2.1.0/gems/rack-1.5.2/lib/rack/conditionalget.rb:35:in `call'
  vendor/bundle/ruby/2.1.0/gems/rack-1.5.2/lib/rack/head.rb:11:in `call'
  vendor/bundle/ruby/2.1.0/gems/actionpack-4.0.2/lib/action_dispatch/middleware/params_parser.rb:27:in `call'
  vendor/bundle/ruby/2.1.0/gems/actionpack-4.0.2/lib/action_dispatch/middleware/flash.rb:241:in `call'
  vendor/bundle/ruby/2.1.0/gems/rack-1.5.2/lib/rack/session/abstract/id.rb:225:in `context'
  vendor/bundle/ruby/2.1.0/gems/rack-1.5.2/lib/rack/session/abstract/id.rb:220:in `call'
  vendor/bundle/ruby/2.1.0/gems/actionpack-4.0.2/lib/action_dispatch/middleware/cookies.rb:486:in `call'
  vendor/bundle/ruby/2.1.0/gems/activerecord-4.0.2/lib/active_record/query_cache.rb:36:in `call'
  vendor/bundle/ruby/2.1.0/gems/activerecord-4.0.2/lib/active_record/connection_adapters/abstract/connection_pool.rb:626:in `call'
  vendor/bundle/ruby/2.1.0/gems/activerecord-4.0.2/lib/active_record/migration.rb:369:in `call'
  vendor/bundle/ruby/2.1.0/gems/actionpack-4.0.2/lib/action_dispatch/middleware/callbacks.rb:29:in `block in call'
  vendor/bundle/ruby/2.1.0/gems/activesupport-4.0.2/lib/active_support/callbacks.rb:373:in `_run__928559686495229391__call__callbacks'
  vendor/bundle/ruby/2.1.0/gems/activesupport-4.0.2/lib/active_support/callbacks.rb:80:in `run_callbacks'
  vendor/bundle/ruby/2.1.0/gems/actionpack-4.0.2/lib/action_dispatch/middleware/callbacks.rb:27:in `call'
  vendor/bundle/ruby/2.1.0/gems/actionpack-4.0.2/lib/action_dispatch/middleware/reloader.rb:64:in `call'
  vendor/bundle/ruby/2.1.0/gems/actionpack-4.0.2/lib/action_dispatch/middleware/remote_ip.rb:76:in `call'
  vendor/bundle/ruby/2.1.0/gems/actionpack-4.0.2/lib/action_dispatch/middleware/debug_exceptions.rb:17:in `call'
  vendor/bundle/ruby/2.1.0/gems/actionpack-4.0.2/lib/action_dispatch/middleware/show_exceptions.rb:30:in `call'
  vendor/bundle/ruby/2.1.0/gems/railties-4.0.2/lib/rails/rack/logger.rb:38:in `call_app'
  vendor/bundle/ruby/2.1.0/gems/railties-4.0.2/lib/rails/rack/logger.rb:20:in `block in call'
  vendor/bundle/ruby/2.1.0/gems/activesupport-4.0.2/lib/active_support/tagged_logging.rb:67:in `block in tagged'
  vendor/bundle/ruby/2.1.0/gems/activesupport-4.0.2/lib/active_support/tagged_logging.rb:25:in `tagged'
  vendor/bundle/ruby/2.1.0/gems/activesupport-4.0.2/lib/active_support/tagged_logging.rb:67:in `tagged'
  vendor/bundle/ruby/2.1.0/gems/railties-4.0.2/lib/rails/rack/logger.rb:20:in `call'
  vendor/bundle/ruby/2.1.0/gems/actionpack-4.0.2/lib/action_dispatch/middleware/request_id.rb:21:in `call'
  vendor/bundle/ruby/2.1.0/gems/rack-1.5.2/lib/rack/methodoverride.rb:21:in `call'
  vendor/bundle/ruby/2.1.0/gems/rack-1.5.2/lib/rack/runtime.rb:17:in `call'
  vendor/bundle/ruby/2.1.0/gems/activesupport-4.0.2/lib/active_support/cache/strategy/local_cache.rb:83:in `call'
  vendor/bundle/ruby/2.1.0/gems/rack-1.5.2/lib/rack/lock.rb:17:in `call'
  vendor/bundle/ruby/2.1.0/gems/actionpack-4.0.2/lib/action_dispatch/middleware/static.rb:64:in `call'
  vendor/bundle/ruby/2.1.0/gems/rack-1.5.2/lib/rack/sendfile.rb:112:in `call'
  vendor/bundle/ruby/2.1.0/gems/railties-4.0.2/lib/rails/engine.rb:511:in `call'
  vendor/bundle/ruby/2.1.0/gems/railties-4.0.2/lib/rails/application.rb:97:in `call'
  /usr/local/rvm/gems/ruby-2.1.1/gems/passenger-4.0.48/lib/phusion_passenger/rack/thread_handler_extension.rb:74:in `process_request'
  /usr/local/rvm/gems/ruby-2.1.1/gems/passenger-4.0.48/lib/phusion_passenger/request_handler/thread_handler.rb:141:in `accept_and_process_next_request'
  /usr/local/rvm/gems/ruby-2.1.1/gems/passenger-4.0.48/lib/phusion_passenger/request_handler/thread_handler.rb:109:in `main_loop'
  /usr/local/rvm/gems/ruby-2.1.1/gems/passenger-4.0.48/lib/phusion_passenger/request_handler.rb:448:in `block (3 levels) in start_threads'


  Rendered vendor/bundle/ruby/2.1.0/gems/actionpack-4.0.2/lib/action_dispatch/middleware/templates/rescues/_source.erb (0.9ms)
  Rendered vendor/bundle/ruby/2.1.0/gems/actionpack-4.0.2/lib/action_dispatch/middleware/templates/rescues/_trace.erb (2.0ms)
  Rendered vendor/bundle/ruby/2.1.0/gems/actionpack-4.0.2/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb (1.8ms)
  Rendered vendor/bundle/ruby/2.1.0/gems/actionpack-4.0.2/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb within rescues/layout (20.3ms)

Thank you!


Solution

  • It sounds like the wrap_parameters code is confused by the fact that your model is namespaced inside the Mongo module.

    It also sounds like you don't actually need parameter wrapping so the easiest thing is to disable it - there should be a wrap_parameters initializer. You can re-enable it on a controller by controller basis if you need to.