Description
This class in an abstraction layer to the attachments/ folder. It allows access to the folder content in a way that mimics the working of ActiveRecord
The Attachment class inherits from the ruby core File class
Folder structure The attachement folder structure example: AttachmentPWD
|
- 1 - this directory level represents the nodes, folder name = node id
| |
| - 3.image.gif
| - 4.another_image.gif
|
- 2
|
- 1.icon.gif
- 2.another_icon.gif
General usage
attachment = Attachment.new("images/my_image.gif", :node_id => 1)
This will create an instance of an attachment that belongs to node with ID = 0 Nothing has bee saved yet
attachment.save
This will save the attachment in the attachment directory structure
You can inspect the saved instance:
attachment.node_id attachment.id attachment.filename attachment.fullpath attachments = Attachment.find(:all)
Creates an array instance that contains all the attachments
Attachment.find(:all, :conditions => {:node_id => 1})
Creates an array instance that contains all the attachments for node with ID=1
Attachment.find('test.gif', :conditions => {:node_id => 1})
Retrieves the test.gif image that is associated with node 1
| AttachmentPwd | = | ENV["RAILS_ENV"] == "test" ? File.join(RAILS_ROOT, 'tmp', 'attachments') : File.join( RAILS_ROOT, 'attachments') |
| Set the path to the attachment storage | ||
| [RW] | filename | |
| [R] | id | |
| [RW] | node_id | |
| [RW] | tempfile |
Return the attachment instance(s) based on the find parameters
[ show source ]
# File app/models/attachment.rb, line 124
124: def self.find(*args)
125: options = args.extract_options!
126: dir = Dir.new(AttachmentPwd)
127:
128: # makes the find request and stores it to resources
129: return_value = case args.first
130: when :all, :first, :last
131: attachments = []
132: if options[:conditions] && options[:conditions][:node_id]
133: node_id = options[:conditions][:node_id].to_s
134: raise "Node with ID=#{node_id} does not exist" unless Node.exists?(node_id)
135: if (File.exist?( File.join(AttachmentPwd, node_id)))
136: node_dir = Dir.new( File.join(AttachmentPwd, node_id) )
137: node_dir.each do |attachment|
138: next unless (attachment =~ /^(.+)$/) == 0 && !File.directory?(attachment)
139: attachments << Attachment.new(:filename => $1, :node_id => node_id.to_i)
140: end
141: end
142: else
143: dir.each do |node|
144: next unless node =~ /^\d*$/
145: node_dir = Dir.new( File.join(AttachmentPwd, node) )
146: node_dir.each do |attachment|
147: next unless (attachment =~ /^(.+)$/) == 0 && !File.directory?(attachment)
148: attachments << Attachment.new(:filename => $1, :node_id => node.to_i)
149: end
150: end
151: attachments.sort! {|a,b| a.filename <=> b.filename }
152: end
153:
154: # return based on the request arguments
155: case args.first
156: when :first
157: attachments.first
158: when :last
159: attachments.last
160: else
161: attachments
162: end
163: else
164: # in this routine we find the attachment by file name and node id
165: filename = args.first
166: attachments = []
167: raise "You need to supply a node id in the condition parameter" unless options[:conditions] && options[:conditions][:node_id]
168: node_id = options[:conditions][:node_id].to_s
169: raise "Node with ID=#{node_id} does not exist" unless Node.exists?(node_id)
170: node_dir = Dir.new( File.join(AttachmentPwd, node_id) )
171: node_dir.each do |attachment|
172: next unless ((attachment =~ /^(.+)$/) == 0 && $1 == filename)
173: attachments << Attachment.new(:filename => $1, :node_id => node_id.to_i)
174: end
175: raise "Could not find Attachment with filename #{filename}" if attachments.empty?
176: attachments.first
177: end
178: return return_value
179: end
Initializes the attachment instance
[ show source ]
# File app/models/attachment.rb, line 74
74: def initialize(*args)
75: options = args.extract_options!
76: @filename = options[:filename]
77: @node_id = options[:node_id]
78: #@id = options[:id]
79: @tempfile = args[0] || options[:tempfile]
80:
81: if File.exists?(fullpath) && File.file?(fullpath)
82: super(fullpath, 'rb+')
83: @initialfile = fullpath.clone
84: elsif @tempfile && File.exists?(@tempfile)
85: super(@tempfile, 'rb+')
86: elsif @tempfile && File.basename(@tempfile) != ''
87: @initialfile = File.join( RAILS_ROOT, 'tmp', File.basename(@tempfile))
88: super(@initialfile, 'wb+')
89: else
90: raise "No physical file available"
91: end
92:
93: end
Class method that returns the path to the attachment storage
[ show source ]
# File app/models/attachment.rb, line 182
182: def self.pwd
183: AttachmentPwd
184: end
Deletes the file that the instance is pointing to from memory
[ show source ]
# File app/models/attachment.rb, line 115
115: def delete
116: self.close
117: if ( !@initialfile || (File.dirname(@initialfile) == File.join(RAILS_ROOT, 'tmp')) )
118: raise "No physical file to delete"
119: end
120: FileUtils.rm(@initialfile)
121: end
Retruns the full path of an attachment on the file system
[ show source ]
# File app/models/attachment.rb, line 187
187: def fullpath
188: File.join(AttachmentPwd, @node_id.to_s, @filename.to_s)
189: end
Closes the current file handle, this writes the content to the file system
[ show source ]
# File app/models/attachment.rb, line 96
96: def save
97: if File.exists?(fullpath) && File.file?(fullpath)
98: self.close
99: else
100: raise "Node with ID=#{@node_id} does not exist" unless @node_id && Node.exists?(@node_id)
101:
102: @filename ||= File.basename(@tempfile)
103: FileUtils.mkdir(File.dirname(fullpath)) unless File.exists?(File.dirname(fullpath))
104: self.close
105: FileUtils.cp(self.path, fullpath) if @intialfile != fullpath
106: if ( @initialfile && @initialfile != fullpath )
107: # If we are still a temp file
108: FileUtils.rm(@initialfile)
109: end
110: @initialfile = fullpath.clone
111: end
112: end
Provide a JSON representation of this object that can be understood by components of the web interface
[ show source ]
# File app/models/attachment.rb, line 193
193: def to_json(options={})
194: {
195: :filename => @filename,
196: :size => File.size(self.fullpath),
197: :created_at => self.ctime
198: }.to_json(options)
199: end