Frage

ich ein Modell haben, lassen Sie uns Attachments sagen, dass attachment_fu verwendet Datei-Uploads vom Benutzer zu akzeptieren. Ich möchte „tiefere Kopie“ (oder in Ruby-ese, tiefere Klon) eine Anlage, so dass ein völlig neues binäres Objekt in der „db_files“ Tabelle erstellen.

Ich habe festgestellt, dass es nicht ganz ein gelöstes Problem noch ist. Dieses Blog-Posting: http://www.williambharding.com/blog / Schienen / Schienen-schneller-clonecopy-of-attachment_fu-images /

Zeigt eine Methode, die für das Dateisystem-basierter Speicher angeblich arbeitet. Für db-basierten Geschäfte, schlägt die „tiefe Kopie“. Eine neue „Anlage“ wird erstellt, aber es nutzt die bereits vorhandenen db_file_id, wodurch eine flache Kopie durchgeführt wird.

Innerhalb attachment_fu der db_file_backend.rb Ich sehe die speichern Methode:

      # Saves the data to the DbFile model
      def save_to_storage
        if save_attachment?
          (db_file || build_db_file).data = temp_data
          db_file.save!
          self.class.update_all ['db_file_id = ?', self.db_file_id = db_file.id], ['id = ?', id]
        end
        true
      end

Also, ich versuche, diese zu entschlüsseln, und ich glaube „build_db_file“ einige metaprogramming magische Abkürzung für DbFile.new Ruby ist, obwohl ich das nicht bestätigen kann (greppen die Quelle nicht auf diesen Aspekt zeigt, noch kann ich es auf Google zu finden) .

Ich bin nicht ganz sicher, was es tut, aber meine Theorie ist, dass die DB_File von der Quelle des „Deep Kopie“ Versuchs (in dem verknüpften Code) obj als Teil kopiert wird somit einfach auslöst eine sparen anstelle eines erstellen.

war Meine erste Theorie, dass die Eltern (Attachment) Objekt würde auf „neu“ auf eine tiefe Kopie Versuch, so habe ich so etwas wie:

 def save_to_storage
    if save_attachment?
      if self.new_record?
        db_file = DbFile.new :data => temp_data
        self.class.update_all ['db_file_id = ?', self.db_file_id = db_file.id], ['id = ?', id]
      end
    end
    true
  end

Das funktioniert tatsächlich für geklonte Objekte in Ordnung, aber leider alle Tests für die regelmäßige, nicht geklont das Hochladen von Dateien fehlschlagen. Das Attachment-Objekt wird erstellt, aber keine Daten geschrieben wird DB_File. Theorie ist, dass das übergeordnete Objekt zuerst gespeichert wird, dann ist die DB_File Sachen später geschrieben wird, so new_record? false zurück.

So, als ein Experiment habe ich beschlossen, versuchen:

  def save_to_storage
    if save_attachment?
      if self.new_record?
        db_file = DbFile.new :data => temp_data
        self.class.update_all ['db_file_id = ?', self.db_file_id = db_file.id], ['id = ?', id]
      else
        (db_file || build_db_file).data = temp_data
        db_file.save!
        self.class.update_all ['db_file_id = ?', self.db_file_id = db_file.id], ['id = ?', id]
      #end
    end
    true
  end

Das funktioniert zum Teil - die DB_File bevölkert wird, aber dann bekomme ich einen Fehler auf db_file.save! -., Dass DB_File sagen will, ist gleich Null

Also, ich bin irgendwie zunichte gemacht. Ich kann einen weiteren Versuch und Irrtum tun, aber an diesem Punkt habe ich mein begrenztes Verständnis dafür, wie dieses Plugin funktioniert getroffen. Ich habe wirklich nicht erwartet, oder wollen sie so viel Zeit verbringen, so bin ich nur ungern weiter zu versuchen und erkunden attachment_fu, aber ich fürchte, ich werde in den Kaninchenbau haben zu gehen, um es herauszufinden. Irgendwelche Ideen oder Gedanken?

Danke !!

War es hilfreich?

Lösung 2

Okay, also statt herauszufinden, wie eine neue DB_File zu schaffen (was in unserem speziellen Fall verschwenderisch ist), habe ich nur Affen gepatcht destroy_file, um nur die DB_File zu löschen, wenn es keine weiteren Befestigungssätze sind auf sie zeigen. Dies kann nicht sinnvoll sein, wenn Sie jemand erlauben, eine Anlage zu „modifizieren“ DB_File in situ , aber da wir dies nicht tun, funktioniert dies sehr gut.

Technoweenie::AttachmentFu::Backends::DbFileBackend.module_eval do
  protected
  def destroy_file
    if db_file && self.class.count( :conditions =>["id <> ? AND db_file_id = ?", self.id, db_file.id] ) == 0
      db_file.destroy 
    end
  end
end

Andere Tipps

Dies ist nur eine Teilantwort Erläuterung des build_db_file Anruf

Wie Sie vermutet, führt die build_db_file Aufruf einer Methode erzeugt durch die Schaffung ein belongs_to Verein . Der Verein wird hier erstellt:

def self.included(base) #:nodoc:
   Object.const_set(:DbFile, Class.new(ActiveRecord::Base)) unless Object.const_defined?(:DbFile)
   base.belongs_to  :db_file, :class_name => '::DbFile', :foreign_key => 'db_file_id'
end

So ist die (db_file || build_db_file) Anweisung nimmt ein vorhandenes zugehöriges DbFile Objekt oder einen neuen erstellt, wenn es gleich Null ist, und weist die TEMP_DATA seines Binärfelds data. Die temp_data ist wahrscheinlich der Byte-Array mit den Daten aus dem Formular.

Und ich habe eine Frage (ich nicht auf Ihre Frage äußern können) - warum Sie db_file.save! nicht aufrufen, nachdem sie mit

Erstellen
db_file = DbFile.new :data => temp_data

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top