Is it possible to create a reminder for a modified Mongooid embedded document field in Ruby on Rails?


Is there a way to run a callback only if an embedded document field was changed?

Currently, the following runs the callback on a normal field only if it was changed:

class user
  field :email, type: String
  embeds_many :connections, cascade_callbacks: true
  before_save :run_callback, :if => :email_changed?
  before_save :run_connection_callback, :if => :connections_changed?  # DOES NOT WORK

Mongoid won't define the method connections_changed? for you, but you can define it yourself by using a virtual field in User to keep track of when an embedded connection gets changed. That is:

class User

  # define reader/writer methods for @connections_changed
  attr_accessor :connections_changed

  def connections_changed?

  # the connections are no longer considered changed after the persistence action
  after_save { self.connections_changed = false }

  before_save :run_connection_callback, :if => :connections_changed?


class Connection
  embedded_in :user

  before_save :tell_user_about_change, :if => :changed?

  def tell_user_about_change
    user.connections_changed = true

One shortcoming of this method is that user.connections_changed only gets set when the document is saved. The callbacks are cascaded in such a way that the Connection before_save callback gets called first and then the User before save callback, which allows the above code to work for this use case. But if you need to know whether any connections have changed before calling save, you'll need to find another method.