Rails:如果满足某些条件,我如何运行before_save?

我有一个我调用的before_save方法重命名上传的图像。

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 

该方法是我的Item模型的一部分。

当我创建一个新项目或需要更新与项目相关联的图像时,这很有用……但问题是,如果我需要更新项目而不是图像,则randomize_file_name方法仍会运行并重命名文件数据库(虽然不是文件本身,显然)。

所以,我想我需要想办法只运行randomize_file_name如果一个文件包含在表单提交中…但我不知道如何解决这个问题。

使用脏对象 。

 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 
 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 

仅检查文件是否已更改。 90%的时间都有效

继续并在每次保存时调用你的before_save方法但是作为你现在称之为“保存之前”的方法的第一步,你应该有一个if条件来测试你需要的特定情况。

只需在function顶部快速检查并返回,如果您不需要做任何事情。

 def randomize_file_name return unless screen_file_name # or whatever check you need to do extension = File.extname(screen_file_name).downcase key = ActiveSupport::SecureRandom.hex(8) self.screen.instance_write(:file_name, "#{key}#{extension}") end 

评论后编辑:

你可以使用Simone Carletti提到的脏对象,或者你可以发挥创意。

在模型中:

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

forms如下:

 <%= f.hidden_field :some_random_field_name_for_you_to_rename, :value => "1" %>