Search code examples
ruby-on-rails-3.2mongoid3

Mongoid Identity Map setting not taking effect in Rails console


It does not appear that the identity_map setting is getting picked up from the config/mongoid.yml file.

Here's the file:

development:
  sessions:
    default:
      uri: mongodb://localhost:27017/test_development
      options: &defaultopts
        op_timeout: 60
        allow_dynamic_fields: false
        identity_map_enabled: true
        preload_models: true
        raise_not_found_error: false

When this is run through RAILS_ENV=development rails console the map is not turned on:

$ RAILS_ENV=development rails c
Loading development environment (Rails 3.2.13)
[1] pry(main)> Mongoid.using_identity_map?
=> false
[2] pry(main)> Mongoid.identity_map_enabled?
=> false

Even an attempt to manually load Mongoid and the file doesn't change it:

[3] pry(main)> require 'mongoid'
=> false
[4] pry(main)> Mongoid.load!("./config/mongoid.yml")
=> {"sessions"=>
  {"default"=>
    {"uri"=>"mongodb://localhost:27017/test_development",
     "options"=>
      {"op_timeout"=>60,
       "allow_dynamic_fields"=>false,
       "identity_map_enabled"=>true,
       "preload_models"=>true,
       "raise_not_found_error"=>false}}}}
[5] pry(main)> Mongoid.using_identity_map?
=> false
[6] pry(main)> Mongoid.identity_map_enabled?
=> false

Only if I manually set the value does it take affect:

[8] pry(main)> Mongoid.identity_map_enabled = true
=> true
[9] pry(main)> Mongoid.using_identity_map?                                                                                                                                                                                                    
=> true
[10] pry(main)> Mongoid.identity_map_enabled?
=> true

Why is the setting not being loaded correctly?

This issue is happening using Rails 3.2.13 and Mongoid 3.1.2.


Solution

  • :options shouldn't be nested in :default. Mongoid is expecting to see mongoid.yml in the format:

    development:
      sessions:
        default:
          uri: mongodb://localhost:27017/test_development
      options:
        op_timeout: 60
        allow_dynamic_fields: false
        identity_map_enabled: true
        preload_models: true
        raise_not_found_error: false
    

    See source where :options are being loaded.

     $ pry
     [1] pry(main)> require 'mongoid'
     => true
     [2] pry(main)> Mongoid.load!("./mongoid.yml", :production)
     => {"sessions"=>
        {"default"=>{"database"=>"mongoid_prod", "hosts"=>["localhost:27017"]}},
        "options"=>{"identity_map_enabled"=>true, "include_root_in_json"=>true}}
     [3] pry(main)> Mongoid.using_identity_map?
     => true
     [4] pry(main)>
    

    EDIT: As pointed out by @cbmanica, there are multiple places where options can be set. For example we could have:

    development:
      sessions:
        default:
          uri: mongodb://localhost:27017/test_development
          options:
            consistency: :strong
      options:
        op_timeout: 60
    

    For the options that are set on the MongoDB database, they cannot be nested inside of session. See source for the defaults.