Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails: How do I run a before_save only if certain conditions are met?

I have a before_save method that I call that renames an uploaded image.

before_save :randomize_file_name

def randomize_file_name
  extension = File.extname(screen_file_name).downcase
  key = ActiveSupport::SecureRandom.hex(8)
  self.screen.instance_write(:file_name, "#{key}#{extension}")
end

That method is part of my Item model.

That works great when I create a new item or need to update the image associated with an item...but the problem is that if I need to update an item but NOT the image, the randomize_file_name method still gets run and renames the file in the database (though not the file itself, obviously).

So, I'm thinking I need to figure out a way to only run randomize_file_name if a file is included in the form submission...but I'm not sure how to pull that off.

like image 500
Shpigford Avatar asked Apr 28 '10 18:04

Shpigford


3 Answers

Use dirty objects.

before_save :randomize_file_name

def randomize_file_name
  # assuming the field that holds the name
  # is called screen_file_name
  if screen_file_name_changed?
    extension = File.extname(screen_file_name).downcase
    key = ActiveSupport::SecureRandom.hex(8)
    self.screen.instance_write(:file_name, "#{key}#{extension}")
  end
end
like image 173
Simone Carletti Avatar answered Nov 18 '22 15:11

Simone Carletti


before_save :randomize_file_name

def randomize_file_name
  if screen_file_name
    extension = File.extname(screen_file_name).downcase
    key = ActiveSupport::SecureRandom.hex(8)
    return self.screen.instance_write(:file_name, "#{key}#{extension}") unless !screen_changed?
  end
end

This checks only if the file has changed. Works 90% of the time

like image 45
theCrab Avatar answered Nov 18 '22 16:11

theCrab


go ahead and make your before_save method called on every save but as a first step inside the method you are now having called "before save" you should have an if condition that tests for the specific case you need.

like image 1
imightbeinatree at Cloudspace Avatar answered Nov 18 '22 15:11

imightbeinatree at Cloudspace