mongoid_globalize icon indicating copy to clipboard operation
mongoid_globalize copied to clipboard

.build and save results in nil attributes

Open brentkirby opened this issue 13 years ago • 2 comments

I'm having some weird issues using nested attributes and building embedded models.

When using .build and specifying attributes, on save the embedded model creates an embedded translation doc, with the proper locale set. However, all of its attributes are blank.

For instance, I have a page model, and an embedded Content model. Content is subclassed (perhaps thats the culprit?) with a model called TextBlock which has a "body" attribute.

page.contents.build({ body: "some content" }, TextBlock)
# misc code here
page.save

Upon save inspecting the embedded TextBlock I have one embedded translation for :en (default locale) but its body, as well as the body on the model itself are both blank.

I'm wondering if its something to do with the changes mongoid made recently with how embedded docs persist mentioned here because if I re-save the embedded doc after the parent is saved, the attributes/translations are properly saved

class Page
  after_save :resave_contents

  def resave_contents
    self.contents.each(&:save)
  end
end

page.contents.first.inspect #=> <TextBlock _id: 4ee6e3644dd9624091000010, _type: "TextBlock", created_at: 2011-12-13 05:32:20 UTC, updated_at: 2011-12-13 05:32:20 UTC, position: 2, body: "some content">

All translations are also set properly.

In addition, as mentioned in the mongoid link above, when updating embedded docs with update_attributes, all attrs/translations are updated perfectly, but using model.attributes= and model.write_attribute(key, value) or model.write_attribute(key, value, :locale => I18n.locale) don't seem to persist either.

I tried overriding the nested_attributes callback (contents_attributes=) and the documents update with the exception of translated attributes. Going through the code also got me to try doc.globalize.write(locale, key, value) but the updated attrs still don't persist.

Without translation enabled everything saves properly, and I'm wondering if this isn't an issue created with how mongoid handles setting embedded docs on the parent as of version 2.2.0. When creating/updating non-embedded docs everything works as expected.

I'm happy to fork and test a few things out, I was just wondering if anyone had any thoughts :)

brentkirby avatar Dec 13 '11 06:12 brentkirby

Hello, Brent, I absolutely didn't consider option when translatable model will be embedded...

So if you can examine this question I will be pleased :)

Gem creates fields for embedded translation in before_save callback, looks like it doesn't call on embedded models when you save Page model.

mikdiet avatar Dec 13 '11 08:12 mikdiet

Apparently this is how mongoid is handling embed callbacks for performance reasons (makes sense). The next release should include a after_build callback which may be the way to resolve this.

Right now the solution is to use embed.create instead of embed.build when creating embedded docs on a parent. This will call the save callbacks to fire and it will work properly.

I started looking into detecting embedded docs with translations and manually firing callbacks but that seems like a little much to solve the issue :) I'll leave it open and keep an eye on it though since I'm using Globalize in a cms engine we're working on for translations. Its definitely the cleanest implementation I've seen yet, so awesome work by the way!

brentkirby avatar Dec 13 '11 18:12 brentkirby