Reputation: 582
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
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