18

In my model Shop I'm saving image url in logo_ori and use that to make thumbnails using before_update.

# shop.rb
before_update :run_blitline_job

private

def run_blitline_job
  # uses logo_ori to make thumbnails
end

However I found out that when I'm saving other attributes (eg: editing shop's profile in a form) it also runs before_update. How do I confine its execution when only logo_ori is saved?

I've tried this :

before_update :run_blitline_job, :if => :logo_ori?

but it still runs before_update if I already have logo_ori saved earlier.

hsym
  • 4,217
  • 2
  • 20
  • 30

3 Answers3

39
before_update :run_blitline_job, :if => :logo_ori_changed?

This will run the callback every time the logo_ori attribute changes. You can also use strings to implement multiple conditionals:

before_update :run_blitline_job, :if => proc { !logo_ori_was && logo_ori_changed? }
Ulysse BN
  • 10,116
  • 7
  • 54
  • 82
John H
  • 2,488
  • 1
  • 21
  • 35
  • 4
    Wouldn't you want to do a proc for that? `:if => proc { !logo_ori_was && logo_ori_changed? }` I guess it's a matter of preference, but I think the intention is a little clearer. – Chris Peters Aug 21 '13 at 20:11
  • Yeah actually, in the case of multiple operands I would prefer a proc or lambda also. – John H Aug 22 '13 at 08:43
3

You are close, you want something like this:

before_update { |shop| shop.run_blitline_job if shop.logo_ori_changed? }

sources:

http://api.rubyonrails.org/classes/ActiveRecord/Callbacks.html

http://api.rubyonrails.org/classes/ActiveModel/Dirty.html

Brad Werth
  • 17,411
  • 10
  • 63
  • 88
0

its simple you can use ActiveModel::Dirty (checkout the documentation), it is available in all models in rails 3

before_update { |shop| shop.run_blitline_job if shop.logo_ori_changed? }
Muhamamd Awais
  • 2,385
  • 14
  • 25