halfbyte-mongoid_grid 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.txt +59 -0
- data/lib/mongoid/grid.rb +182 -0
- data/lib/rack/grid.rb +59 -0
- data/test/fixtures/harmony.png +0 -0
- data/test/fixtures/mr_t.jpg +0 -0
- data/test/fixtures/test1.txt +1 -0
- data/test/fixtures/test2.txt +1 -0
- data/test/fixtures/unixref.pdf +0 -0
- data/test/test_helper.rb +45 -0
- data/test/test_mongoid_grid.rb +284 -0
- data/test/test_rack_grid.rb +0 -0
- metadata +96 -0
data/README.txt
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
Mongoid::Grid / Rack::Grid
|
2
|
+
|
3
|
+
Mongoid::Grid is a plugin for mongoid that uses GridFS. Heavily inspired
|
4
|
+
by grip (http://github.com/jnunemaker/grip)
|
5
|
+
|
6
|
+
Rack::Grid is used to serve a GridFS file from rack. Mostly copied
|
7
|
+
from http://github.com/skinandbones/rack-gridfs
|
8
|
+
|
9
|
+
Download the source at
|
10
|
+
http://github.com/dusty/mongoid_grid
|
11
|
+
|
12
|
+
|
13
|
+
Installation
|
14
|
+
|
15
|
+
Put the libraries in your project however you want.
|
16
|
+
|
17
|
+
You could make a gem to install or use with bundler.
|
18
|
+
|
19
|
+
# git clone http://github.com/dusty/mongoid_grid
|
20
|
+
# cd mongoid_grid
|
21
|
+
# gem build mongoid_grid.gemspec
|
22
|
+
|
23
|
+
Then require the libraries you want to use.
|
24
|
+
|
25
|
+
require 'mongoid/grid'
|
26
|
+
require 'rack/grid'
|
27
|
+
|
28
|
+
|
29
|
+
Usage
|
30
|
+
|
31
|
+
class Monkey
|
32
|
+
include Mongoid::Document
|
33
|
+
include Mongoid::Grid
|
34
|
+
field :name
|
35
|
+
attachment :image
|
36
|
+
end
|
37
|
+
|
38
|
+
m = Monkey.create(:name => 'name')
|
39
|
+
|
40
|
+
# To add an attachment
|
41
|
+
m.image = File.open('/tmp/me.jpg')
|
42
|
+
m.save
|
43
|
+
|
44
|
+
# To remove an attachment
|
45
|
+
m.image = nil
|
46
|
+
m.save
|
47
|
+
|
48
|
+
# To get the attachment
|
49
|
+
m.image.read
|
50
|
+
|
51
|
+
# To use Rack::Grid with Sinatra
|
52
|
+
|
53
|
+
configure do
|
54
|
+
use Rack::Grid, :database => 'my_db'
|
55
|
+
end
|
56
|
+
|
57
|
+
<img src="<%= m.image_url %>" alt="<%= m.image_name %>" />
|
58
|
+
|
59
|
+
|
data/lib/mongoid/grid.rb
ADDED
@@ -0,0 +1,182 @@
|
|
1
|
+
require 'mime/types'
|
2
|
+
require 'mongoid'
|
3
|
+
require 'active_support/all'
|
4
|
+
module Mongoid
|
5
|
+
module Grid
|
6
|
+
|
7
|
+
def self.included(base)
|
8
|
+
base.send(:extend, ClassMethods)
|
9
|
+
base.send(:include, InstanceMethods)
|
10
|
+
base.class_inheritable_accessor :attachment_types
|
11
|
+
base.attachment_types = []
|
12
|
+
|
13
|
+
end
|
14
|
+
|
15
|
+
module ClassMethods
|
16
|
+
|
17
|
+
##
|
18
|
+
# Declare an attachment for the object
|
19
|
+
#
|
20
|
+
# eg: attachment :image
|
21
|
+
def attachment(name,prefix='grid')
|
22
|
+
##
|
23
|
+
# Callbacks to handle the attachment saving and deleting
|
24
|
+
after_save :create_attachments
|
25
|
+
after_save :delete_attachments
|
26
|
+
after_destroy :destroy_attachments
|
27
|
+
|
28
|
+
##
|
29
|
+
# Fields for the attachment.
|
30
|
+
#
|
31
|
+
# Only the _id is really needed, the others are helpful cached
|
32
|
+
# so you don't need to hit GridFS
|
33
|
+
field "#{name}_id".to_sym, :type => BSON::ObjectID
|
34
|
+
field "#{name}_name".to_sym, :type => String
|
35
|
+
field "#{name}_size".to_sym, :type => Integer
|
36
|
+
field "#{name}_type".to_sym, :type => String
|
37
|
+
|
38
|
+
##
|
39
|
+
# Add this name to the attachment_types
|
40
|
+
attachment_types.push(name).uniq!
|
41
|
+
|
42
|
+
##
|
43
|
+
# Return the GridFS object.
|
44
|
+
# eg: image.filename, image.read
|
45
|
+
define_method(name) do
|
46
|
+
grid.get(attributes["#{name}_id"]) if attributes["#{name}_id"]
|
47
|
+
end
|
48
|
+
|
49
|
+
##
|
50
|
+
# Returns true if attachment exists.
|
51
|
+
# eg: image?
|
52
|
+
define_method("#{name}?") do
|
53
|
+
!!attributes["#{name}_id"]
|
54
|
+
end
|
55
|
+
|
56
|
+
##
|
57
|
+
# Create a method to set the attachment
|
58
|
+
# eg: object.image = File.open('/tmp/somefile.jpg')
|
59
|
+
define_method("#{name}=") do |file|
|
60
|
+
if file.respond_to?(:read)
|
61
|
+
send(:create_attachment, name, file)
|
62
|
+
else
|
63
|
+
send(:delete_attachment, name, send("#{name}_id"))
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
##
|
68
|
+
# Return the relative URL to the file for use with Rack::Grid
|
69
|
+
# eg: /grid/4ba69fde8c8f369a6e000003/somefile.png
|
70
|
+
define_method("#{name}_url") do
|
71
|
+
_id = send("#{name}_id")
|
72
|
+
_name = send("#{name}_name")
|
73
|
+
["/#{prefix}", _id, _name].join('/') if _id && _name
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
77
|
+
|
78
|
+
##
|
79
|
+
# Accessor to GridFS
|
80
|
+
def grid
|
81
|
+
@grid ||= Mongo::Grid.new(Mongoid.database)
|
82
|
+
end
|
83
|
+
|
84
|
+
##
|
85
|
+
# # All the attachments types for this class
|
86
|
+
# def attachment_types
|
87
|
+
# super + (@attachment_types ||= [])
|
88
|
+
# end
|
89
|
+
|
90
|
+
end
|
91
|
+
|
92
|
+
module InstanceMethods
|
93
|
+
|
94
|
+
private
|
95
|
+
##
|
96
|
+
# Accessor to GridFS
|
97
|
+
def grid
|
98
|
+
@grid ||= self.class.grid
|
99
|
+
end
|
100
|
+
|
101
|
+
##
|
102
|
+
# Holds queue of attachments to create
|
103
|
+
def create_attachment_queue
|
104
|
+
@create_attachment_queue ||= {}
|
105
|
+
end
|
106
|
+
|
107
|
+
##
|
108
|
+
# Holds queue of attachments to delete
|
109
|
+
def delete_attachment_queue
|
110
|
+
@delete_attachment_queue ||= {}
|
111
|
+
end
|
112
|
+
|
113
|
+
##
|
114
|
+
# Attachments we need to add after save.
|
115
|
+
def create_attachment(name,file)
|
116
|
+
if file.respond_to?(:read)
|
117
|
+
filename = file.respond_to?(:original_filename) ?
|
118
|
+
file.original_filename : File.basename(file.path)
|
119
|
+
type = MIME::Types.type_for(filename).first
|
120
|
+
mime = type ? type.content_type : "application/octet-stream"
|
121
|
+
send("#{name}_id=", BSON::ObjectID.new) if attributes["#{name}_id"].nil?
|
122
|
+
send("#{name}_name=", filename)
|
123
|
+
send("#{name}_size=", File.size(file))
|
124
|
+
send("#{name}_type=", mime)
|
125
|
+
create_attachment_queue[name] = file
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
##
|
130
|
+
# Save an attachment to GridFS
|
131
|
+
def create_grid_attachment(name,file)
|
132
|
+
file.rewind if file.respond_to?(:rewind)
|
133
|
+
grid.delete(attributes["#{name}_id"])
|
134
|
+
grid.put(
|
135
|
+
file.read,
|
136
|
+
:filename => attributes["#{name}_name"],
|
137
|
+
:content_type => attributes["#{name}_type"],
|
138
|
+
:_id => attributes["#{name}_id"]
|
139
|
+
)
|
140
|
+
create_attachment_queue.delete(name)
|
141
|
+
end
|
142
|
+
|
143
|
+
##
|
144
|
+
# Attachments we need to remove after save
|
145
|
+
def delete_attachment(name,id)
|
146
|
+
delete_attachment_queue[name] = id if id.is_a?(BSON::ObjectID)
|
147
|
+
send("#{name}_id=", nil)
|
148
|
+
send("#{name}_name=", nil)
|
149
|
+
send("#{name}_size=", nil)
|
150
|
+
send("#{name}_type=", nil)
|
151
|
+
end
|
152
|
+
|
153
|
+
##
|
154
|
+
# Delete an attachment from GridFS
|
155
|
+
def delete_grid_attachment(name,id)
|
156
|
+
grid.delete(id) if id.is_a?(BSON::ObjectID)
|
157
|
+
delete_attachment_queue.delete(name)
|
158
|
+
end
|
159
|
+
|
160
|
+
##
|
161
|
+
# Create attachments marked for creation
|
162
|
+
def create_attachments
|
163
|
+
create_attachment_queue.each {|k,v| create_grid_attachment(k,v)}
|
164
|
+
end
|
165
|
+
|
166
|
+
##
|
167
|
+
# Delete attachments marked for deletion
|
168
|
+
def delete_attachments
|
169
|
+
delete_attachment_queue.each {|k,v| delete_grid_attachment(k,v)}
|
170
|
+
end
|
171
|
+
|
172
|
+
##
|
173
|
+
# Deletes all attachments from document
|
174
|
+
def destroy_attachments
|
175
|
+
self.class.attachment_types.each do |name|
|
176
|
+
delete_grid_attachment(name, send("#{name}_id"))
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
data/lib/rack/grid.rb
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'timeout'
|
2
|
+
require 'mongo'
|
3
|
+
|
4
|
+
module Rack
|
5
|
+
class Grid
|
6
|
+
class ConnectionError < StandardError ; end
|
7
|
+
|
8
|
+
attr_reader :hostname, :port, :database, :prefix, :db
|
9
|
+
|
10
|
+
def initialize(app, options = {})
|
11
|
+
options = {
|
12
|
+
:hostname => 'localhost',
|
13
|
+
:prefix => 'grid',
|
14
|
+
:port => Mongo::Connection::DEFAULT_PORT,
|
15
|
+
}.merge(options)
|
16
|
+
|
17
|
+
@app = app
|
18
|
+
@hostname = options[:hostname]
|
19
|
+
@port = options[:port]
|
20
|
+
@database = options[:database]
|
21
|
+
@prefix = options[:prefix]
|
22
|
+
@db = nil
|
23
|
+
|
24
|
+
connect!
|
25
|
+
end
|
26
|
+
|
27
|
+
##
|
28
|
+
# Strip the _id out of the path. This allows the user to send something
|
29
|
+
# like /grid/4ba69fde8c8f369a6e000003/filename.jpg to find the file
|
30
|
+
# with an id of 4ba69fde8c8f369a6e000003.
|
31
|
+
def call(env)
|
32
|
+
request = Rack::Request.new(env)
|
33
|
+
if request.path_info =~ /^\/#{prefix}\/(\w+).*$/
|
34
|
+
grid_request($1)
|
35
|
+
else
|
36
|
+
@app.call(env)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
##
|
41
|
+
# Get file from GridFS or return a 404
|
42
|
+
def grid_request(id)
|
43
|
+
file = Mongo::Grid.new(db).get(BSON::ObjectID.from_string(id))
|
44
|
+
[200, {'Content-Type' => file.content_type}, [file.read]]
|
45
|
+
rescue Mongo::GridError, BSON::InvalidObjectID
|
46
|
+
[404, {'Content-Type' => 'text/plain'}, ['File not found.']]
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
def connect!
|
51
|
+
Timeout::timeout(5) do
|
52
|
+
@db = Mongo::Connection.new(hostname).db(database)
|
53
|
+
end
|
54
|
+
rescue StandardError => e
|
55
|
+
raise ConnectionError, "Timeout connecting to GridFS (#{e.to_s})"
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
end
|
Binary file
|
Binary file
|
@@ -0,0 +1 @@
|
|
1
|
+
test1
|
@@ -0,0 +1 @@
|
|
1
|
+
test2
|
Binary file
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'tempfile'
|
2
|
+
require 'pp'
|
3
|
+
require 'shoulda'
|
4
|
+
#require 'matchy'
|
5
|
+
require 'mocha'
|
6
|
+
require 'mongoid'
|
7
|
+
|
8
|
+
require File.expand_path(File.dirname(__FILE__) + '/../lib/mongoid/grid')
|
9
|
+
|
10
|
+
Mongoid.configure do |config|
|
11
|
+
name = "mongoid_grid_test"
|
12
|
+
host = "localhost"
|
13
|
+
config.allow_dynamic_fields = false
|
14
|
+
config.master = Mongo::Connection.new.db(name)
|
15
|
+
end
|
16
|
+
|
17
|
+
class Test::Unit::TestCase
|
18
|
+
def setup
|
19
|
+
Mongoid.database.collections.each(&:remove)
|
20
|
+
end
|
21
|
+
|
22
|
+
def assert_difference(expression, difference = 1, message = nil, &block)
|
23
|
+
b = block.send(:binding)
|
24
|
+
exps = Array.wrap(expression)
|
25
|
+
before = exps.map { |e| eval(e, b) }
|
26
|
+
yield
|
27
|
+
exps.each_with_index do |e, i|
|
28
|
+
error = "#{e.inspect} didn't change by #{difference}"
|
29
|
+
error = "#{message}.\n#{error}" if message
|
30
|
+
assert_equal(before[i] + difference, eval(e, b), error)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def assert_no_difference(expression, message = nil, &block)
|
35
|
+
assert_difference(expression, 0, message, &block)
|
36
|
+
end
|
37
|
+
|
38
|
+
def assert_grid_difference(difference=1, &block)
|
39
|
+
assert_difference("Mongoid.database['fs.files'].find().count", difference, &block)
|
40
|
+
end
|
41
|
+
|
42
|
+
def assert_no_grid_difference(&block)
|
43
|
+
assert_grid_difference(0, &block)
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,284 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class Asset
|
4
|
+
include Mongoid::Document
|
5
|
+
include Mongoid::Grid
|
6
|
+
|
7
|
+
field :title, :type => String
|
8
|
+
attachment :image
|
9
|
+
attachment :file
|
10
|
+
end
|
11
|
+
|
12
|
+
class BaseModel
|
13
|
+
include Mongoid::Document
|
14
|
+
include Mongoid::Grid
|
15
|
+
attachment :file
|
16
|
+
end
|
17
|
+
|
18
|
+
class Image < BaseModel; attachment :image end
|
19
|
+
class Video < BaseModel; attachment :video end
|
20
|
+
|
21
|
+
module Mongoid::GridTestHelpers
|
22
|
+
def all_files
|
23
|
+
[@file, @image, @image2, @test1, @test2]
|
24
|
+
end
|
25
|
+
|
26
|
+
def rewind_files
|
27
|
+
all_files.each { |file| file.rewind }
|
28
|
+
end
|
29
|
+
|
30
|
+
def open_file(name)
|
31
|
+
File.open(File.join(File.dirname(__FILE__), 'fixtures', name), 'r')
|
32
|
+
end
|
33
|
+
|
34
|
+
def grid
|
35
|
+
@grid ||= Mongo::Grid.new(Mongoid.database)
|
36
|
+
end
|
37
|
+
|
38
|
+
def key_names
|
39
|
+
[:id, :name, :type, :size]
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
class Mongoid::GridTest < Test::Unit::TestCase
|
44
|
+
include Mongoid::GridTestHelpers
|
45
|
+
|
46
|
+
def setup
|
47
|
+
super
|
48
|
+
@file = open_file('unixref.pdf')
|
49
|
+
@image = open_file('mr_t.jpg')
|
50
|
+
@image2 = open_file('harmony.png')
|
51
|
+
@test1 = open_file('test1.txt')
|
52
|
+
@test2 = open_file('test2.txt')
|
53
|
+
end
|
54
|
+
|
55
|
+
def teardown
|
56
|
+
all_files.each { |file| file.close }
|
57
|
+
end
|
58
|
+
|
59
|
+
context "Using Grid plugin" do
|
60
|
+
should "add each attachment to attachment_types" do
|
61
|
+
assert_equal [:image, :file], Asset.attachment_types
|
62
|
+
end
|
63
|
+
|
64
|
+
should "add keys for each attachment" do
|
65
|
+
key_names.each do |key|
|
66
|
+
assert Asset.fields.keys.include?("image_#{key}")
|
67
|
+
assert Asset.fields.keys.include?("file_#{key}")
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
context "with inheritance" do
|
72
|
+
should "add attachment to attachment_types" do
|
73
|
+
assert_equal [:file], BaseModel.attachment_types
|
74
|
+
end
|
75
|
+
|
76
|
+
should "inherit attachments from superclass, but not share other inherited class attachments" do
|
77
|
+
assert_equal [:file, :image], Image.attachment_types
|
78
|
+
assert_equal [:file, :video], Video.attachment_types
|
79
|
+
end
|
80
|
+
|
81
|
+
should "add inherit keys from superclass" do
|
82
|
+
key_names.each do |key|
|
83
|
+
assert BaseModel.fields.keys.include?("file_#{key}")
|
84
|
+
assert Image.fields.keys.include?("file_#{key}")
|
85
|
+
assert Video.fields.keys.include?("file_#{key}")
|
86
|
+
assert Video.fields.keys.include?("video_#{key}")
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
context "Assigning new attachments to document" do
|
93
|
+
setup do
|
94
|
+
@doc = Asset.create(:image => @image, :file => @file)
|
95
|
+
rewind_files
|
96
|
+
end
|
97
|
+
subject { @doc }
|
98
|
+
|
99
|
+
should "assign GridFS content_type" do
|
100
|
+
assert_equal 'image/jpeg', grid.get(subject.image_id).content_type
|
101
|
+
assert_equal 'application/pdf', grid.get(subject.file_id).content_type
|
102
|
+
end
|
103
|
+
|
104
|
+
should "assign joint keys" do
|
105
|
+
assert_equal 13661, subject.image_size
|
106
|
+
assert_equal 68926, subject.file_size
|
107
|
+
|
108
|
+
assert_equal "image/jpeg", subject.image_type
|
109
|
+
assert_equal "application/pdf", subject.file_type
|
110
|
+
|
111
|
+
assert_not_nil subject.image_id
|
112
|
+
assert_not_nil subject.file_id
|
113
|
+
|
114
|
+
assert subject.image_id.instance_of?(BSON::ObjectID)
|
115
|
+
assert subject.file_id.instance_of?(BSON::ObjectID)
|
116
|
+
end
|
117
|
+
|
118
|
+
should "allow accessing keys through attachment proxy" do
|
119
|
+
assert_equal 13661, subject.image_size
|
120
|
+
assert_equal 68926, subject.file_size
|
121
|
+
|
122
|
+
assert_equal "image/jpeg", subject.image_type
|
123
|
+
assert_equal "application/pdf", subject.file_type
|
124
|
+
|
125
|
+
assert_not_nil subject.image_id
|
126
|
+
assert_not_nil subject.file_id
|
127
|
+
|
128
|
+
# assert subject.image.id.instance_of?(BSON::ObjectID),
|
129
|
+
# assert subject.file.id.instance_of?(BSON::ObjectID)
|
130
|
+
end
|
131
|
+
|
132
|
+
should "proxy unknown methods to GridIO object" do
|
133
|
+
assert_equal subject.image_id, subject.image.files_id
|
134
|
+
assert_equal 'image/jpeg', subject.image.content_type
|
135
|
+
assert_equal 'mr_t.jpg', subject.image.filename
|
136
|
+
assert_equal 13661, subject.image.file_length
|
137
|
+
end
|
138
|
+
|
139
|
+
should "assign file name from path if original file name not available" do
|
140
|
+
assert_equal 'mr_t.jpg', subject.image_name
|
141
|
+
assert_equal 'unixref.pdf', subject.file_name
|
142
|
+
end
|
143
|
+
|
144
|
+
should "save attachment contents correctly" do
|
145
|
+
assert_equal @file.read, subject.file.read
|
146
|
+
assert_equal @image.read, subject.image.read
|
147
|
+
end
|
148
|
+
|
149
|
+
should "know that attachment exists" do
|
150
|
+
assert subject.image?
|
151
|
+
assert subject.file?
|
152
|
+
end
|
153
|
+
|
154
|
+
should "clear assigned attachments so they don't get uploaded twice" do
|
155
|
+
Mongo::Grid.any_instance.expects(:put).never
|
156
|
+
subject.save
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
context "Updating existing attachment" do
|
161
|
+
setup do
|
162
|
+
@doc = Asset.create(:file => @test1)
|
163
|
+
assert_no_grid_difference do
|
164
|
+
@doc.file = @test2
|
165
|
+
@doc.save!
|
166
|
+
end
|
167
|
+
rewind_files
|
168
|
+
end
|
169
|
+
subject { @doc }
|
170
|
+
|
171
|
+
should "not change attachment id" do
|
172
|
+
assert !subject.file_id_changed?
|
173
|
+
end
|
174
|
+
|
175
|
+
should "update keys" do
|
176
|
+
assert_equal 'test2.txt', subject.file_name
|
177
|
+
assert_equal "text/plain", subject.file_type
|
178
|
+
assert_equal 5, subject.file_size
|
179
|
+
end
|
180
|
+
|
181
|
+
should "update GridFS" do
|
182
|
+
grid_obj = grid.get(subject.file_id)
|
183
|
+
assert_equal 'test2.txt', grid_obj.filename
|
184
|
+
assert_equal 'text/plain', grid_obj.content_type
|
185
|
+
assert_equal 5, grid_obj.file_length
|
186
|
+
assert_equal @test2.read, grid_obj.read
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
context "Updating document but not attachments" do
|
191
|
+
setup do
|
192
|
+
@doc = Asset.create(:image => @image)
|
193
|
+
@doc.update_attributes(:title => 'Updated')
|
194
|
+
@doc.reload
|
195
|
+
rewind_files
|
196
|
+
end
|
197
|
+
subject { @doc }
|
198
|
+
|
199
|
+
should "not affect attachment" do
|
200
|
+
assert_equal @image.read, subject.image.read
|
201
|
+
end
|
202
|
+
|
203
|
+
should "update document attributes" do
|
204
|
+
assert_equal('Updated', subject.title)
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
208
|
+
context "Assigning file where file pointer is not at beginning" do
|
209
|
+
setup do
|
210
|
+
@image.read
|
211
|
+
@doc = Asset.create(:image => @image)
|
212
|
+
@doc.reload
|
213
|
+
rewind_files
|
214
|
+
end
|
215
|
+
subject { @doc }
|
216
|
+
|
217
|
+
should "rewind and correctly store contents" do
|
218
|
+
assert_equal @image.read, subject.image.read
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
context "Setting attachment to nil" do
|
223
|
+
setup do
|
224
|
+
@doc = Asset.create(:image => @image)
|
225
|
+
rewind_files
|
226
|
+
end
|
227
|
+
subject { @doc }
|
228
|
+
|
229
|
+
should "delete attachment after save" do
|
230
|
+
assert_no_grid_difference { subject.image = nil }
|
231
|
+
assert_grid_difference(-1) { subject.save }
|
232
|
+
end
|
233
|
+
|
234
|
+
should "clear nil attachments after save and not attempt to delete again" do
|
235
|
+
Mongo::Grid.any_instance.expects(:delete).once
|
236
|
+
subject.image = nil
|
237
|
+
subject.save
|
238
|
+
Mongo::Grid.any_instance.expects(:delete).never
|
239
|
+
subject.save
|
240
|
+
end
|
241
|
+
end
|
242
|
+
|
243
|
+
context "Retrieving attachment that does not exist" do
|
244
|
+
setup do
|
245
|
+
@doc = Asset.create
|
246
|
+
rewind_files
|
247
|
+
end
|
248
|
+
subject { @doc }
|
249
|
+
|
250
|
+
should "know that the attachment is not present" do
|
251
|
+
assert !subject.image?
|
252
|
+
end
|
253
|
+
|
254
|
+
# should "raise Mongo::GridFileNotFound" do
|
255
|
+
# assert_raises(Mongo::GridFileNotFound) { subject.image.read }
|
256
|
+
# end
|
257
|
+
end
|
258
|
+
|
259
|
+
context "Destroying a document" do
|
260
|
+
setup do
|
261
|
+
@doc = Asset.create(:image => @image)
|
262
|
+
rewind_files
|
263
|
+
end
|
264
|
+
subject { @doc }
|
265
|
+
|
266
|
+
should "remove files from grid fs as well" do
|
267
|
+
assert_grid_difference(-1) { subject.destroy }
|
268
|
+
end
|
269
|
+
end
|
270
|
+
|
271
|
+
context "Assigning file name" do
|
272
|
+
should "default to path" do
|
273
|
+
assert_equal 'mr_t.jpg', Asset.create(:image => @image).image_name
|
274
|
+
end
|
275
|
+
|
276
|
+
should "use original_filename if available" do
|
277
|
+
def @image.original_filename
|
278
|
+
'testing.txt'
|
279
|
+
end
|
280
|
+
doc = Asset.create(:image => @image)
|
281
|
+
assert_equal 'testing.txt', doc.image_name
|
282
|
+
end
|
283
|
+
end
|
284
|
+
end
|
File without changes
|
metadata
ADDED
@@ -0,0 +1,96 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: halfbyte-mongoid_grid
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 0
|
8
|
+
- 2
|
9
|
+
version: 0.0.2
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Jan Krutisch
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2010-05-24 00:00:00 +02:00
|
18
|
+
default_executable:
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: mime-types
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - ">="
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
segments:
|
28
|
+
- 0
|
29
|
+
version: "0"
|
30
|
+
type: :runtime
|
31
|
+
version_requirements: *id001
|
32
|
+
- !ruby/object:Gem::Dependency
|
33
|
+
name: mongoid
|
34
|
+
prerelease: false
|
35
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - ">="
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
segments:
|
40
|
+
- 1
|
41
|
+
- 9
|
42
|
+
version: "1.9"
|
43
|
+
type: :runtime
|
44
|
+
version_requirements: *id002
|
45
|
+
description: Plugin for Mongoid to use GridFS and a Rack helper
|
46
|
+
email: jan+mongoid-grid@krutisch.de
|
47
|
+
executables: []
|
48
|
+
|
49
|
+
extensions: []
|
50
|
+
|
51
|
+
extra_rdoc_files:
|
52
|
+
- README.txt
|
53
|
+
files:
|
54
|
+
- README.txt
|
55
|
+
- lib/mongoid/grid.rb
|
56
|
+
- lib/rack/grid.rb
|
57
|
+
- test/test_helper.rb
|
58
|
+
- test/test_mongoid_grid.rb
|
59
|
+
- test/test_rack_grid.rb
|
60
|
+
- test/fixtures/harmony.png
|
61
|
+
- test/fixtures/mr_t.jpg
|
62
|
+
- test/fixtures/test1.txt
|
63
|
+
- test/fixtures/test2.txt
|
64
|
+
- test/fixtures/unixref.pdf
|
65
|
+
has_rdoc: true
|
66
|
+
homepage: http://github.com/halfbyte/mongoid_grid
|
67
|
+
licenses: []
|
68
|
+
|
69
|
+
post_install_message:
|
70
|
+
rdoc_options: []
|
71
|
+
|
72
|
+
require_paths:
|
73
|
+
- lib
|
74
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
75
|
+
requirements:
|
76
|
+
- - ">="
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
segments:
|
79
|
+
- 0
|
80
|
+
version: "0"
|
81
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
82
|
+
requirements:
|
83
|
+
- - ">="
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
segments:
|
86
|
+
- 0
|
87
|
+
version: "0"
|
88
|
+
requirements: []
|
89
|
+
|
90
|
+
rubyforge_project: none
|
91
|
+
rubygems_version: 1.3.6
|
92
|
+
signing_key:
|
93
|
+
specification_version: 3
|
94
|
+
summary: Plugin for Mongoid to use GridFS and a Rack helper
|
95
|
+
test_files: []
|
96
|
+
|