Search code examples
ruby-on-railsruby-on-rails-3observer-pattern

is there a way to create an observer on a single field?


update, in the end, the solution was to move this to the user model instead of profile. Notice that in profile, i have to check obj.owner.email. It seems that by the time that the profile is reached, obj.owner (user) has already been saved and none of the conditions pass. This works in the other model.

what i'd like to do is limit the number of times emails are sent to when an email field in the users table goes from blank to a valid email. I''ve tried a couple of callback methods but those are causing some problems.

I haven't found too much info on observers. I know you can do all the callback methods there but is there anyway to check on a single field?

profile.rb:

  before_save :send_messages_after_registration!, :if => lambda {|obj| obj.owner.email_changed? && (obj.owner.email_was.nil? || obj.owner.email_was.blank?) }


  def send_messages_after_registration!
    Rails.logger.debug("Entered send_messages_after_registration! with email : " + self.owner.email.to_s)
    after_transaction do
      unless self.owner.email.blank?
        Rails.logger.debug("email.blank? is false with email : " + self.owner.email.to_s)
        JobSeekerNotifier.webinar_notification(self.owner.id).deliver
        Resque.enqueue_in(48.hours, TrackReminderWorker, self.owner.id)
      end
    end
  end

I used before save because it's my understanding that .changed? will always be false if after_save or after_commit. Am I mistaken?

For a moment I thought it might be the after_transaction piece - but the log message is not even being written to the log file.


Solution

  • Try:

    before_save :foo, :if => lambda {|obj| obj.field_name_changed? && obj.field_name == true }
    
    def foo
     #whatever you need
    end