Module: ActsAsFile::ClassMethods

Defined in:
lib/acts_as_file.rb

Overview

ToDo: rename if filename is changed

Instance Method Summary collapse

Instance Method Details

#acts_as_file(params = {}) ⇒ Object

acts_as_file :field => self.instance_method(:filename)



11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/acts_as_file.rb', line 11

def acts_as_file(params = {})
  self.class_eval do
    unless method_defined?(:save_with_file)
      define_method(:save_with_file) do |*args|
        params.each do |field, filename_instance_method|
          field_name = :"@#{field}"
          filename = filename_instance_method.bind(self).call
          content  = self.instance_variable_get(field_name)
          if filename and content
            dirname = File.dirname(filename)
            FileUtils.mkdir_p(dirname) unless Dir.exist?(dirname)
            File.open(filename, 'w') do |f|
              f.flock(File::LOCK_EX) # inter-process locking
              f.sync = true
              f.write(content)
              f.flush
            end
          end
        end
        save_without_file(*args)
      end
      define_method(:save) {|*args| } unless method_defined?(:save)
      alias_method :save_without_file, :save
      alias_method :save, :save_with_file

      params.each do |field, filename_instance_method|
        field_name = :"@#{field}"
        define_method("#{field}=") do |content|
          self.instance_variable_set(field_name, content)
        end
      end

      params.each do |field, filename_instance_method|
        field_name = :"@#{field}"
        define_method(field) do |offset = nil, length = nil|
          if offset || length
            # does not cache in this way
            filename = filename_instance_method.bind(self).call
            return nil unless filename
            return nil unless File.exist?(filename)
            File.open(filename) do |file|
              file.seek(offset) if offset
              file.read(length)
            end
          else
            content = self.instance_variable_get(field_name)
            return content if content
            # if (self.updated_at.nil? or File.mtime(filename) > self.updated_at)
            filename = filename_instance_method.bind(self).call
            return nil unless filename
            return nil unless File.exist?(filename)
            self.instance_variable_set(field_name, File.read(filename))
          end
        end
      end

      define_method(:destroy_with_file) do
        params.each do |field, filename_instance_method|
          field_name = :"@#{field}"
          filename = filename_instance_method.bind(self).call
          File.unlink(filename) if File.exist?(filename)
        end
        destroy_without_file
      end
      define_method(:destroy) {} unless method_defined?(:destroy)
      alias_method :destroy_without_file, :destroy
      alias_method :destroy, :destroy_with_file
    end
  end
end