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

时间:2022-02-27 00:16:43

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

我有一个我调用的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

That method is part of my Item model.

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

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

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

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.

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

4 个解决方案

#1


12  

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

#2


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

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

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

#3


1  

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.

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

#4


0  

Just do a quick check at the top of the function and return if you don't need to do anything.

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

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

Edit after comment:

评论后编辑:

You can use the dirty object as mentioned by Simone Carletti, or you can get creative.

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

In the Model:

在模型中:

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

In the form:

形式如下:

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

#1


12  

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

#2


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

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

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

#3


1  

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.

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

#4


0  

Just do a quick check at the top of the function and return if you don't need to do anything.

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

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

Edit after comment:

评论后编辑:

You can use the dirty object as mentioned by Simone Carletti, or you can get creative.

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

In the Model:

在模型中:

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

In the form:

形式如下:

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