Matt McCormick
Matt McCormick

Reputation: 582

Mongo / Mongoid will create, but not update a model

I have an app which updates a post if it exists, otherwise it creates a new one. This post contains embedded documents:

class Post
  embeds_one :tag, :as => :taggable, :class_name => 'TagSnippet'
end

class TagSnippet
  include Mongoid::Document
  field :name
  embedded_in :taggable, polymorphic: true
end

The post is updated in a controller with the following code:

@post = Post.where(--some criteria which work--).first
if @post
  @post.attributes = params
else
  @post = Post.new(params)
end

@post.save!

This code runs and updates the non-embedded documents, but does not update the embedded docs. Oddly, when I debug in Rubymine, all the attributes of the @post change appropriately (including the embedded ones), but regardless the database does not get updated.

This indicates to me it's some mongo or mongoid problem, but rolling back mongo and mongoid gems produced no change.

Upvotes: 3

Views: 1621

Answers (1)

Sergio Tulentsev
Sergio Tulentsev

Reputation: 230356

I guess that your embedded document is defined like this:

field :subdoc, type: Hash

I bumped into this a couple of times already. Short explanation: Mongoid doesn't track changes inside subhashes.

doc.subdoc.field_a = 1 # won't be tracked

sd = doc.subdoc.dup
sd.field_a = 1
doc.subdoc = sd # should be tracked

So, if Mongoid doesn't detect assignments, it doesn't mark attribute dirty, and therefore doesn't include it in the update operation.

Check this theory by printing doc.subdoc_changed? before saving.

Upvotes: 3

Related Questions