문제

attachment_fu를 사용하여 사용자의 파일 업로드를 수락하는 모델이 있습니다. 나는 "딥 카피"(또는 루비 에스, 딥 클론에서) 부착물을 원하므로 "db_files"테이블에 완전히 새로운 이진 객체를 만듭니다.

나는 그것이 아직 해결 된 문제가 아니라는 것을 알았습니다. 이 블로그 게시 :http://www.williambharding.com/blog/rails/rails-faster-clonecopy-of-attachment_fu-images/

파일 시스템 기반 스토리지에서 작동하는 것으로 추정되는 방법을 보여줍니다. DB 기반 상점의 경우 "딥 카피"가 실패합니다. 새로운 "첨부 파일"이 생성되지만 기존 DB_FILE_ID를 사용하여 얕은 사본을 수행합니다.

attachment_fu의 db_file_backend.rb 내부에 저장 메소드가 나타납니다.

      # 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

그래서 저는 이것을 해독하려고 노력하고 있으며 "build_db_file"은 DBFile의 Ruby Metaprogramming Magic 속기라고 생각합니다.

나는 그것이 무엇을하고 있는지 잘 모르겠지만, 내 이론은 DB_File이 "딥 카피"시도 (링크 된 코드에서)의 일부로 소스 OBJ에서 복사되고 있다는 것입니다. 만들다.

나의 초기 이론은 부모 (첨부 파일) 객체가 깊은 사본 시도에서 "새"로 설정 될 것이라는 것이었다. 따라서 나는 다음과 같은 것을했다.

 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

이것은 실제로 복제 된 객체에 대해 잘 작동하지만 불행히도 정기적 인 복제되지 않은 파일 업로드에 대한 모든 테스트는 실패합니다. 첨부 객체가 생성되지만 DB_FILE에 데이터가 기록되지 않습니다. 이론은 부모 객체가 먼저 저장된 다음 DB_FILE 물건이 나중에 쓰여져 있으므로 New_Record? 거짓을 반환합니다.

따라서 실험으로 나는 시도하기로 결정했다.

  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

그것은 부분적으로 작동합니다 - db_file은 채워졌지만 db_file.save에 오류가 발생합니다! - db_file이 nil이라고 말합니다.

그래서 나는 일종의 stymied입니다. 좀 더 시행 착오를 할 수 있지만이 시점 에서이 플러그인이 어떻게 작동하는지에 대한 제한된 이해를 쳤다. 나는 정말로이 많은 시간을 기대하거나 소비하고 싶지 않았으므로 더 이상 Attachment_fu를 탐색하기를 꺼려하지만 토끼 구멍을 내려 놓기 위해 토끼 구멍을 내려야 할 것이 두렵습니다. 아이디어 나 생각이 있습니까?

감사!!

도움이 되었습니까?

해결책 2

좋아, 따라서 새로운 DB_FILE (특정 경우에 낭비되는)을 만드는 방법을 알아내는 대신 Monkey-Patched Destrove_File만으로도 더 이상 부착 된 레코드가 없으면 DB_FILE 만 삭제합니다. 누군가가 부착물을 "수정"하도록 허용하는 경우 적절하지 않을 수 있습니다. 현장 그러나 우리는 그렇지 않기 때문에 이것은 훌륭하게 작동합니다.

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

다른 팁

이것은 단지 설명을 설명하는 부분적인 반응 일뿐입니다 build_db_file 전화

당신이 의심했듯이, build_db_file 통화는 메소드를 실행합니다 a belongs_to 협회. 협회는 여기에 만들어집니다.

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

그래서 (db_file || build_db_file) 진술은 기존 관련을 취합니다 DbFile 객체, 또는 nil 인 경우 새 제품을 생성하고 Temp_data를 이진 필드에 할당합니다. data. 그만큼 temp_data 아마도 양식의 데이터가 포함 된 바이트 배열 일 것입니다.

그리고 나는 하나의 질문이 있습니다 (당신의 질문에 대해 언급 할 수 없습니다) - 왜 전화하지 않습니까? db_file.save! 함께 만들어 낸 후

db_file = DbFile.new :data => temp_data

?

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top