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

时间:2010-04-28 18:08:13

标签: ruby-on-rails model

我有一个我调用的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的方法...但我不知道如何解决这个问题。

4 个答案:

答案 0 :(得分:12)

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

答案 1 :(得分:4)

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%的时间内工作

答案 2 :(得分:1)

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

答案 3 :(得分:0)

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

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

表格形式:

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