3

Is it possible, that Mongoid, v5.1.2 ignores the returnNewDocument option when used with find_one_and_update?

Consider the following code:

next_number = TrackingId.where(id: id).find_one_and_update({
    :$inc => {
      auto_increment_counter: 1
    }
  },
  upsert: true,
  returnNewDocument: true
).auto_increment_counter

where auto_increment_counter is an Integer field :auto_increment_counter, type: Integer, default: 0 on that class.

However, when no document is found, it creates one, but it doesn't return the newly created document. So I get nil back from find_one_and_update and it breaks.

23tux
  • 14,104
  • 15
  • 88
  • 187

1 Answers1

4

I would suspect that mongoid implementation of find_one_and_update would change the flag of returnNewDocument to return_new_document or $returnNewDocument. I will take a look at the mongoid code base later on and confirm.

Update: So I had a play in pry and looked at the code. I later was able to confirm this in the docs as well. The option you are looking for is return_document, which you set to either :before or :after (see docs: http://www.rubydoc.info/github/mongoid/mongoid/Mongoid%2FContextual%2FMongo%3Afind_one_and_update)

Therefore your query should be:

next_number = TrackingId.where(id: id).find_one_and_update({
    :$inc => {
      auto_increment_counter: 1
    }
  },
  upsert: true,
  return_document: :after
).auto_increment_counter
ABrowne
  • 1,574
  • 1
  • 11
  • 21
  • I wonder what the logic behind naming the argument `return_document` and not `return_new_document` as in mongodb is. – 23tux Apr 19 '16 at 07:45
  • because their implementation has made the decision to use the return_document to be a before/after flag rather than assuming that a document that is returned will be the one before the update. This way it's more explicit than the mongodb api in what to expect it to return. – ABrowne Apr 19 '16 at 07:56