2010-04-28 12 views
12

Ich habe eine Methode namens before_save, die ein hochgeladenes Bild umbenennt.Rails: Wie führe ich ein before_save nur aus, wenn bestimmte Bedingungen erfüllt sind?

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 

Diese Methode ist Teil meines Modells Item.

Das funktioniert gut, wenn ich ein neues Element erstellen oder das mit einem Element verknüpfte Bild aktualisieren muss ... aber das Problem ist, dass, wenn ich ein Element aber nicht das Bild aktualisieren muss, die randomize_file_name Methode noch ausgeführt wird Benennt die Datei in der Datenbank um (natürlich nicht die Datei selbst).

Also, ich denke, ich muss einen Weg finden, nur randomize_file_name ausführen, wenn eine Datei in das Formular Einreichung enthalten ist ... aber ich bin mir nicht sicher, wie man das abziehen.

Antwort

12

Verwenden Sie 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 
+0

Ausführlichere Dokumentation hier: http://apidock.com/rails/ActiveRecord/Dirty –

+1

Dies wird es auch nicht bekommen. Was passiert, wenn der Benutzer eine neue Datei mit demselben Dateinamen hochlädt? In diesem Fall ist Dateiname gleich, aber Sie möchten möglicherweise einen anderen Schlüssel. –

0

Machen Sie einfach einen kurzen Check oben in der Funktion und kehren Sie zurück, wenn Sie nichts unternehmen müssen.

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 

bearbeiten nach Kommentar:

Sie können das schmutzige Objekt verwenden, wie von Simone Carletti erwähnt, oder Sie können kreativ.

Im Modell:

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 der Form:

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

Aber das Problem ist, dass, wenn das Formular keinen Upload enthält, dann zieht es einfach "screen_file_name" aus der Datenbank für diese ID ... Ich muss speziell überprüfen, ob das Formular Einreichung enthält alles für das Bildfeld ... und ich weiß nicht, wie ich das vom Modell machen soll. – Shpigford

1

voran gehen und Ihre BEFORE_SAVE Methode auf jedem in der Methode, die Sie jetzt genannt haben, aber als ersten Schritt zu speichern genannt machen Vor dem Speichern sollten Sie eine if-Bedingung haben, die auf den speziellen Fall hin prüft, den Sie benötigen.

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 

Diese prüft nur, ob die Datei geändert hat. Funktioniert 90% der Zeit

Verwandte Themen