carrierwave 2.2.0 → 3.0.0

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.

Potentially problematic release.


This version of carrierwave might be problematic. Click here for more details.

Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +151 -63
  3. data/lib/carrierwave/compatibility/paperclip.rb +4 -2
  4. data/lib/carrierwave/downloader/base.rb +27 -13
  5. data/lib/carrierwave/downloader/remote_file.rb +12 -9
  6. data/lib/carrierwave/locale/en.yml +5 -3
  7. data/lib/carrierwave/mount.rb +31 -50
  8. data/lib/carrierwave/mounter.rb +115 -50
  9. data/lib/carrierwave/orm/activerecord.rb +12 -60
  10. data/lib/carrierwave/processing/mini_magick.rb +15 -13
  11. data/lib/carrierwave/processing/rmagick.rb +11 -15
  12. data/lib/carrierwave/processing/vips.rb +12 -12
  13. data/lib/carrierwave/sanitized_file.rb +50 -79
  14. data/lib/carrierwave/storage/abstract.rb +5 -5
  15. data/lib/carrierwave/storage/file.rb +6 -5
  16. data/lib/carrierwave/storage/fog.rb +78 -69
  17. data/lib/carrierwave/test/matchers.rb +11 -7
  18. data/lib/carrierwave/uploader/cache.rb +18 -10
  19. data/lib/carrierwave/uploader/callbacks.rb +1 -1
  20. data/lib/carrierwave/uploader/configuration.rb +10 -4
  21. data/lib/carrierwave/uploader/{content_type_whitelist.rb → content_type_allowlist.rb} +17 -15
  22. data/lib/carrierwave/uploader/{content_type_blacklist.rb → content_type_denylist.rb} +19 -14
  23. data/lib/carrierwave/uploader/dimension.rb +66 -0
  24. data/lib/carrierwave/uploader/{extension_whitelist.rb → extension_allowlist.rb} +17 -15
  25. data/lib/carrierwave/uploader/{extension_blacklist.rb → extension_denylist.rb} +18 -13
  26. data/lib/carrierwave/uploader/file_size.rb +2 -2
  27. data/lib/carrierwave/uploader/processing.rb +42 -7
  28. data/lib/carrierwave/uploader/proxy.rb +16 -3
  29. data/lib/carrierwave/uploader/store.rb +43 -6
  30. data/lib/carrierwave/uploader/url.rb +1 -1
  31. data/lib/carrierwave/uploader/versions.rb +137 -132
  32. data/lib/carrierwave/uploader.rb +10 -8
  33. data/lib/carrierwave/utilities/file_name.rb +47 -0
  34. data/lib/carrierwave/utilities/uri.rb +14 -11
  35. data/lib/carrierwave/utilities.rb +1 -0
  36. data/lib/carrierwave/validations/active_model.rb +4 -6
  37. data/lib/carrierwave/version.rb +1 -1
  38. data/lib/carrierwave.rb +9 -17
  39. data/lib/generators/uploader_generator.rb +3 -3
  40. metadata +54 -46
  41. /data/lib/generators/templates/{uploader.rb → uploader.rb.erb} +0 -0
@@ -11,7 +11,7 @@ module CarrierWave
11
11
  prepend Module.new {
12
12
  def initialize(*)
13
13
  super
14
- @file, @filename, @cache_id, @identifier = nil
14
+ @file, @filename, @cache_id, @identifier, @deduplication_index = nil
15
15
  end
16
16
  }
17
17
  end
@@ -34,9 +34,25 @@ module CarrierWave
34
34
  @filename
35
35
  end
36
36
 
37
+ ##
38
+ # Returns a filename which doesn't conflict with already-stored files.
39
+ #
40
+ # === Returns
41
+ #
42
+ # [String] the filename with suffix added for deduplication
43
+ #
44
+ def deduplicated_filename
45
+ return unless filename
46
+
47
+ parts = filename.split('.')
48
+ basename = parts.shift
49
+ basename.sub!(/ ?\(\d+\)\z/, '')
50
+ ([basename.to_s + (@deduplication_index ? "(#{@deduplication_index})" : '')] + parts).join('.')
51
+ end
52
+
37
53
  ##
38
54
  # Calculates the path where the file should be stored. If +for_file+ is given, it will be
39
- # used as the filename, otherwise +CarrierWave::Uploader#filename+ is assumed.
55
+ # used as the identifier, otherwise +CarrierWave::Uploader#identifier+ is assumed.
40
56
  #
41
57
  # === Parameters
42
58
  #
@@ -46,7 +62,7 @@ module CarrierWave
46
62
  #
47
63
  # [String] the store path
48
64
  #
49
- def store_path(for_file=filename)
65
+ def store_path(for_file=identifier)
50
66
  File.join([store_dir, full_filename(for_file)].compact)
51
67
  end
52
68
 
@@ -60,7 +76,7 @@ module CarrierWave
60
76
  # [new_file (File, IOString, Tempfile)] any kind of file object
61
77
  #
62
78
  def store!(new_file=nil)
63
- cache!(new_file) if new_file && ((@cache_id != parent_cache_id) || @cache_id.nil?)
79
+ cache!(new_file) if new_file && !cached?
64
80
  if !cache_only && @file && @cache_id
65
81
  with_callbacks(:store, new_file) do
66
82
  new_file = storage.store!(@file)
@@ -69,7 +85,8 @@ module CarrierWave
69
85
  cache_storage.delete_dir!(cache_path(nil))
70
86
  end
71
87
  @file = new_file
72
- @cache_id = @identifier = nil
88
+ @identifier = storage.identifier
89
+ @cache_id = @deduplication_index = nil
73
90
  @staged = false
74
91
  end
75
92
  end
@@ -89,10 +106,30 @@ module CarrierWave
89
106
  end
90
107
  end
91
108
 
109
+ ##
110
+ # Look for a store path which doesn't collide with the given already-stored paths.
111
+ # It is done by adding a index number as the suffix.
112
+ # For example, if there's 'image.jpg' and the @deduplication_index is set to 2,
113
+ # The stored file will be named as 'image(2).jpg'.
114
+ #
115
+ # === Parameters
116
+ #
117
+ # [current_paths (Array[String])] List of paths for already-stored files
118
+ #
119
+ def deduplicate(current_paths)
120
+ @deduplication_index = nil
121
+ return unless current_paths.include?(store_path)
122
+
123
+ (2..current_paths.size + 1).each do |i|
124
+ @deduplication_index = i
125
+ break unless current_paths.include?(store_path)
126
+ end
127
+ end
128
+
92
129
  private
93
130
 
94
131
  def full_filename(for_file)
95
- for_file
132
+ forcing_extension(for_file)
96
133
  end
97
134
 
98
135
  def storage
@@ -23,7 +23,7 @@ module CarrierWave
23
23
  if file.respond_to?(:path)
24
24
  path = encode_path(file.path.sub(File.expand_path(root), ''))
25
25
 
26
- if host = asset_host
26
+ if (host = asset_host)
27
27
  if host.respond_to? :call
28
28
  "#{host.call(file)}#{path}"
29
29
  else
@@ -1,6 +1,76 @@
1
1
  module CarrierWave
2
2
  module Uploader
3
3
  module Versions
4
+ class Builder
5
+ def initialize(name)
6
+ @name = name
7
+ @options = {}
8
+ @blocks = []
9
+ @klass = nil
10
+ end
11
+
12
+ def configure(options, &block)
13
+ @options.merge!(options)
14
+ @blocks << block if block
15
+ @klass = nil
16
+ end
17
+
18
+ def build(superclass)
19
+ return @klass if @klass
20
+ @klass = Class.new(superclass)
21
+ superclass.const_set("#{@name.to_s.camelize}VersionUploader", @klass)
22
+
23
+ @klass.version_names += [@name]
24
+ @klass.versions = {}
25
+ @klass.processors = []
26
+ @klass.version_options = @options
27
+ @klass.class_eval <<-RUBY, __FILE__, __LINE__ + 1
28
+ # Regardless of what is set in the parent uploader, do not enforce the
29
+ # move_to_cache config option on versions because it moves the original
30
+ # file to the version's target file.
31
+ #
32
+ # If you want to enforce this setting on versions, override this method
33
+ # in each version:
34
+ #
35
+ # version :thumb do
36
+ # def move_to_cache
37
+ # true
38
+ # end
39
+ # end
40
+ #
41
+ def move_to_cache
42
+ false
43
+ end
44
+
45
+ # Need to rely on the parent version's identifier, as versions don't have its own one.
46
+ def identifier
47
+ parent_version.identifier
48
+ end
49
+ RUBY
50
+ @blocks.each { |block| @klass.class_eval(&block) }
51
+ @klass
52
+ end
53
+
54
+ def deep_dup
55
+ other = dup
56
+ other.instance_variable_set(:@blocks, @blocks.dup)
57
+ other
58
+ end
59
+
60
+ def method_missing(name, *args)
61
+ super
62
+ rescue NoMethodError => e
63
+ raise e.exception <<~ERROR
64
+ #{e.message}
65
+ If you're trying to configure a version, do it inside a block like `version(:thumb) { self.#{name} #{args.map(&:inspect).join(', ')} }`.
66
+ ERROR
67
+ end
68
+
69
+ def respond_to_missing?(*)
70
+ super
71
+ end
72
+ end
73
+
4
74
  extend ActiveSupport::Concern
5
75
 
6
76
  include CarrierWave::Uploader::Callbacks
@@ -11,9 +81,8 @@ module CarrierWave
11
81
  self.versions = {}
12
82
  self.version_names = []
13
83
 
14
- attr_accessor :parent_cache_id, :parent_version
84
+ attr_accessor :parent_version
15
85
 
16
- after :cache, :assign_parent_cache_id
17
86
  after :cache, :cache_versions!
18
87
  after :store, :store_versions!
19
88
  after :remove, :remove_versions!
@@ -23,7 +92,7 @@ module CarrierWave
23
92
  prepend Module.new {
24
93
  def initialize(*)
25
94
  super
26
- @versions, @versions_to_cache, @versions_to_store = nil
95
+ @versions = nil
27
96
  end
28
97
  }
29
98
  end
@@ -51,80 +120,33 @@ module CarrierWave
51
120
  # process :scale => [200, 200]
52
121
  # end
53
122
  #
123
+ # version :square, :unless => :invalid_image_type? do
124
+ # process :scale => [100, 100]
125
+ # end
126
+ #
54
127
  # end
55
128
  #
56
129
  def version(name, options = {}, &block)
57
130
  name = name.to_sym
58
- build_version(name, options)
131
+ versions[name] ||= Builder.new(name)
132
+ versions[name].configure(options, &block)
59
133
 
60
- versions[name].class_eval(&block) if block
61
- versions[name]
62
- end
134
+ class_eval <<-RUBY, __FILE__, __LINE__ + 1
135
+ def #{name}
136
+ versions[:#{name}]
137
+ end
138
+ RUBY
63
139
 
64
- def recursively_apply_block_to_versions(&block)
65
- versions.each do |name, version|
66
- version.class_eval(&block)
67
- version.recursively_apply_block_to_versions(&block)
68
- end
140
+ versions[name]
69
141
  end
70
142
 
71
143
  private
72
144
 
73
- def build_version(name, options)
74
- if !versions.has_key?(name)
75
- uploader = Class.new(self)
76
- const_set("Uploader#{uploader.object_id}".tr('-', '_'), uploader)
77
- uploader.version_names += [name]
78
- uploader.versions = {}
79
- uploader.processors = []
80
- uploader.version_options = options
81
-
82
- uploader.class_eval <<-RUBY, __FILE__, __LINE__ + 1
83
- # Define the enable_processing method for versions so they get the
84
- # value from the parent class unless explicitly overwritten
85
- def self.enable_processing(value=nil)
86
- self.enable_processing = value if value
87
- if defined?(@enable_processing) && !@enable_processing.nil?
88
- @enable_processing
89
- else
90
- superclass.enable_processing
91
- end
92
- end
93
-
94
- # Regardless of what is set in the parent uploader, do not enforce the
95
- # move_to_cache config option on versions because it moves the original
96
- # file to the version's target file.
97
- #
98
- # If you want to enforce this setting on versions, override this method
99
- # in each version:
100
- #
101
- # version :thumb do
102
- # def move_to_cache
103
- # true
104
- # end
105
- # end
106
- #
107
- def move_to_cache
108
- false
109
- end
110
- RUBY
111
-
112
- class_eval <<-RUBY, __FILE__, __LINE__ + 1
113
- def #{name}
114
- versions[:#{name}]
115
- end
116
- RUBY
117
- else
118
- uploader = Class.new(versions[name])
119
- const_set("Uploader#{uploader.object_id}".tr('-', '_'), uploader)
120
- uploader.processors = []
121
- uploader.version_options = uploader.version_options.merge(options)
122
- end
123
-
124
- # Add the current version hash to class attribute :versions
125
- self.versions = versions.merge(name => uploader)
145
+ def inherited(subclass)
146
+ # To prevent subclass version changes affecting superclass versions
147
+ subclass.versions = versions.deep_dup
148
+ super
126
149
  end
127
-
128
150
  end # ClassMethods
129
151
 
130
152
  ##
@@ -138,7 +160,7 @@ module CarrierWave
138
160
  return @versions if @versions
139
161
  @versions = {}
140
162
  self.class.versions.each do |name, version|
141
- @versions[name] = version.new(model, mounted_as)
163
+ @versions[name] = version.build(self.class).new(model, mounted_as)
142
164
  @versions[name].parent_version = self
143
165
  end
144
166
  @versions
@@ -161,25 +183,44 @@ module CarrierWave
161
183
  #
162
184
  # === Returns
163
185
  #
164
- # [Boolean] True when the version exists according to its :if condition
186
+ # [Boolean] True when the version exists according to its :if or :unless condition
165
187
  #
166
188
  def version_exists?(name)
167
189
  name = name.to_sym
168
190
 
169
- return false unless self.class.versions.has_key?(name)
191
+ return false unless versions.has_key?(name)
192
+
193
+ if_condition = versions[name].class.version_options[:if]
194
+ unless_condition = versions[name].class.version_options[:unless]
170
195
 
171
- condition = self.class.versions[name].version_options[:if]
172
- if(condition)
173
- if(condition.respond_to?(:call))
174
- condition.call(self, :version => name, :file => file)
196
+ if if_condition
197
+ if if_condition.respond_to?(:call)
198
+ if_condition.call(self, :version => name, :file => file)
175
199
  else
176
- send(condition, file)
200
+ send(if_condition, file)
201
+ end
202
+ elsif unless_condition
203
+ if unless_condition.respond_to?(:call)
204
+ !unless_condition.call(self, :version => name, :file => file)
205
+ else
206
+ !send(unless_condition, file)
177
207
  end
178
208
  else
179
209
  true
180
210
  end
181
211
  end
182
212
 
213
+ ##
214
+ # Copies the parent's cache_id when caching a version file.
215
+ # This behavior is not essential but it makes easier to understand
216
+ # that the cached files are generated by the single upload attempt.
217
+ #
218
+ def cache!(*args)
219
+ self.cache_id = parent_version.cache_id if parent_version
220
+
221
+ super
222
+ end
223
+
183
224
  ##
184
225
  # When given a version name as a parameter, will return the url for that version
185
226
  # This also works with nested versions.
@@ -221,60 +262,25 @@ module CarrierWave
221
262
  # versions if their parameters somehow have changed.
222
263
  #
223
264
  def recreate_versions!(*names)
224
- # Some files could possibly not be stored on the local disk. This
225
- # doesn't play nicely with processing. Make sure that we're only
226
- # processing a cached file
227
- #
228
- # The call to store! will trigger the necessary callbacks to both
229
- # process this version and all sub-versions
265
+ # As well as specified versions, we need to reprocess versions
266
+ # that are the source of another version.
230
267
 
231
- if names.any?
232
- set_versions_to_cache_and_store(names)
233
- store!(file)
234
- reset_versions_to_cache_and_store
235
- else
236
- cache! if !cached?
237
- store!
268
+ self.cache_id = CarrierWave.generate_cache_id
269
+ derived_versions.each do |name, v|
270
+ v.cache!(file) if names.empty? || !(v.descendant_version_names & names).empty?
238
271
  end
239
- end
240
-
241
- private
242
-
243
- def set_versions_to_cache_and_store(names)
244
- @versions_to_cache = source_versions_of(names)
245
- @versions_to_store = active_versions_with_names_in(@versions_to_cache + names)
246
- end
247
-
248
- def reset_versions_to_cache_and_store
249
- @versions_to_cache, @versions_to_store = nil, nil
250
- end
251
-
252
- def versions_to_cache
253
- @versions_to_cache || dependent_versions
254
- end
255
-
256
- def versions_to_store
257
- @versions_to_store || active_versions
258
- end
259
-
260
- def source_versions_of(requested_names)
261
- versions.inject([]) do |sources, (name, uploader)|
262
- next sources unless requested_names.include?(name)
263
- next sources unless source_name = uploader.class.version_options[:from_version]
264
-
265
- sources << [source_name, versions[source_name]]
266
- end.uniq
267
- end
268
-
269
- def active_versions_with_names_in(names)
270
- active_versions.select do |pretendent_name, uploader|
271
- names.include?(pretendent_name)
272
+ active_versions.each do |name, v|
273
+ v.store! if names.empty? || names.include?(name)
272
274
  end
275
+ ensure
276
+ @cache_id = nil
273
277
  end
274
278
 
275
- def assign_parent_cache_id(file)
276
- active_versions.each do |name, uploader|
277
- uploader.parent_cache_id = @cache_id
279
+ protected
280
+
281
+ def descendant_version_names
282
+ [version_name] + derived_versions.flat_map do |name, version|
283
+ version.descendant_version_names
278
284
  end
279
285
  end
280
286
 
@@ -284,16 +290,18 @@ module CarrierWave
284
290
  end
285
291
  end
286
292
 
287
- def dependent_versions
293
+ private
294
+
295
+ def derived_versions
288
296
  active_versions.reject do |name, v|
289
297
  v.class.version_options[:from_version]
290
- end.to_a + sibling_versions.select do |name, v|
298
+ end.to_a + active_sibling_versions.select do |name, v|
291
299
  v.class.version_options[:from_version] == self.class.version_names.last
292
300
  end.to_a
293
301
  end
294
302
 
295
- def sibling_versions
296
- parent_version.try(:versions) || []
303
+ def active_sibling_versions
304
+ parent_version&.active_versions || []
297
305
  end
298
306
 
299
307
  def full_filename(for_file)
@@ -305,14 +313,11 @@ module CarrierWave
305
313
  end
306
314
 
307
315
  def cache_versions!(new_file)
308
- versions_to_cache.each do |name, v|
309
- v.send(:cache_id=, @cache_id)
310
- v.cache!(new_file)
311
- end
316
+ derived_versions.each { |name, v| v.cache!(new_file) }
312
317
  end
313
318
 
314
319
  def store_versions!(new_file)
315
- versions_to_store.each { |name, v| v.store!(new_file) }
320
+ active_versions.each { |name, v| v.store!(new_file) }
316
321
  end
317
322
 
318
323
  def remove_versions!
@@ -7,11 +7,12 @@ require "carrierwave/uploader/cache"
7
7
  require "carrierwave/uploader/store"
8
8
  require "carrierwave/uploader/download"
9
9
  require "carrierwave/uploader/remove"
10
- require "carrierwave/uploader/extension_whitelist"
11
- require "carrierwave/uploader/extension_blacklist"
12
- require "carrierwave/uploader/content_type_whitelist"
13
- require "carrierwave/uploader/content_type_blacklist"
10
+ require "carrierwave/uploader/extension_allowlist"
11
+ require "carrierwave/uploader/extension_denylist"
12
+ require "carrierwave/uploader/content_type_allowlist"
13
+ require "carrierwave/uploader/content_type_denylist"
14
14
  require "carrierwave/uploader/file_size"
15
+ require "carrierwave/uploader/dimension"
15
16
  require "carrierwave/uploader/processing"
16
17
  require "carrierwave/uploader/versions"
17
18
  require "carrierwave/uploader/default_url"
@@ -52,11 +53,12 @@ module CarrierWave
52
53
  include CarrierWave::Uploader::Store
53
54
  include CarrierWave::Uploader::Download
54
55
  include CarrierWave::Uploader::Remove
55
- include CarrierWave::Uploader::ExtensionWhitelist
56
- include CarrierWave::Uploader::ExtensionBlacklist
57
- include CarrierWave::Uploader::ContentTypeWhitelist
58
- include CarrierWave::Uploader::ContentTypeBlacklist
56
+ include CarrierWave::Uploader::ExtensionAllowlist
57
+ include CarrierWave::Uploader::ExtensionDenylist
58
+ include CarrierWave::Uploader::ContentTypeAllowlist
59
+ include CarrierWave::Uploader::ContentTypeDenylist
59
60
  include CarrierWave::Uploader::FileSize
61
+ include CarrierWave::Uploader::Dimension
60
62
  include CarrierWave::Uploader::Processing
61
63
  include CarrierWave::Uploader::Versions
62
64
  include CarrierWave::Uploader::DefaultUrl
@@ -0,0 +1,47 @@
1
+ module CarrierWave
2
+ module Utilities
3
+ module FileName
4
+
5
+ ##
6
+ # Returns the part of the filename before the extension. So if a file is called 'test.jpeg'
7
+ # this would return 'test'
8
+ #
9
+ # === Returns
10
+ #
11
+ # [String] the first part of the filename
12
+ #
13
+ def basename
14
+ split_extension(filename)[0] if filename
15
+ end
16
+
17
+ ##
18
+ # Returns the file extension
19
+ #
20
+ # === Returns
21
+ #
22
+ # [String] extension of file or "" if the file has no extension
23
+ #
24
+ def extension
25
+ split_extension(filename)[1] if filename
26
+ end
27
+
28
+ private
29
+
30
+ def split_extension(filename)
31
+ # regular expressions to try for identifying extensions
32
+ extension_matchers = [
33
+ /\A(.+)\.(tar\.([glx]?z|bz2))\z/, # matches "something.tar.gz"
34
+ /\A(.+)\.([^\.]+)\z/ # matches "something.jpg"
35
+ ]
36
+
37
+ extension_matchers.each do |regexp|
38
+ if filename =~ regexp
39
+ return $1, $2
40
+ end
41
+ end
42
+
43
+ [filename, ""] # In case we weren't able to split the extension
44
+ end
45
+ end # FileName
46
+ end # Utilities
47
+ end # CarrierWave
@@ -3,20 +3,23 @@ require 'uri'
3
3
  module CarrierWave
4
4
  module Utilities
5
5
  module Uri
6
- # based on Ruby < 2.0's URI.encode
7
- SAFE_STRING = URI::REGEXP::PATTERN::UNRESERVED + '\/'
8
- UNSAFE = Regexp.new("[^#{SAFE_STRING}]", false)
6
+ # based on Ruby < 2.0's URI.encode
7
+ PATH_SAFE = URI::REGEXP::PATTERN::UNRESERVED + '\/'
8
+ PATH_UNSAFE = Regexp.new("[^#{PATH_SAFE}]", false)
9
+ NON_ASCII = /[^[:ascii:]]/.freeze
9
10
 
10
11
  private
12
+
11
13
  def encode_path(path)
12
- path.to_s.gsub(UNSAFE) do
13
- us = $&
14
- tmp = ''
15
- us.each_byte do |uc|
16
- tmp << sprintf('%%%02X', uc)
17
- end
18
- tmp
19
- end
14
+ URI::DEFAULT_PARSER.escape(path, PATH_UNSAFE)
15
+ end
16
+
17
+ def encode_non_ascii(str)
18
+ URI::DEFAULT_PARSER.escape(str, NON_ASCII)
19
+ end
20
+
21
+ def decode_uri(str)
22
+ URI::DEFAULT_PARSER.unescape(str)
20
23
  end
21
24
  end # Uri
22
25
  end # Utilities
@@ -1,4 +1,5 @@
1
1
  require 'carrierwave/utilities/uri'
2
+ require 'carrierwave/utilities/file_name'
2
3
 
3
4
  module CarrierWave
4
5
  module Utilities
@@ -12,8 +12,7 @@ module CarrierWave
12
12
 
13
13
  def validate_each(record, attribute, value)
14
14
  record.__send__("#{attribute}_processing_errors").each do |e|
15
- message = (e.message == e.class.to_s) ? :carrierwave_processing_error : e.message
16
- record.errors.add(attribute, message)
15
+ record.errors.add(attribute, :carrierwave_processing_error, message: (e.message != e.class.to_s) && e.message)
17
16
  end
18
17
  end
19
18
  end
@@ -22,8 +21,7 @@ module CarrierWave
22
21
 
23
22
  def validate_each(record, attribute, value)
24
23
  record.__send__("#{attribute}_integrity_errors").each do |e|
25
- message = (e.message == e.class.to_s) ? :carrierwave_integrity_error : e.message
26
- record.errors.add(attribute, message)
24
+ record.errors.add(attribute, :carrierwave_integrity_error, message: (e.message != e.class.to_s) && e.message)
27
25
  end
28
26
  end
29
27
  end
@@ -32,8 +30,7 @@ module CarrierWave
32
30
 
33
31
  def validate_each(record, attribute, value)
34
32
  record.__send__("#{attribute}_download_errors").each do |e|
35
- message = (e.message == e.class.to_s) ? :carrierwave_download_error : e.message
36
- record.errors.add(attribute, message)
33
+ record.errors.add(attribute, :carrierwave_download_error, message: (e.message != e.class.to_s) && e.message)
37
34
  end
38
35
  end
39
36
  end
@@ -58,6 +55,7 @@ module CarrierWave
58
55
  def validates_processing_of(*attr_names)
59
56
  validates_with ProcessingValidator, _merge_attributes(attr_names)
60
57
  end
58
+
61
59
  #
62
60
  ##
63
61
  # Makes the record invalid if the remote file couldn't be downloaded
@@ -1,3 +1,3 @@
1
1
  module CarrierWave
2
- VERSION = "2.2.0"
2
+ VERSION = "3.0.0".freeze
3
3
  end
data/lib/carrierwave.rb CHANGED
@@ -25,16 +25,7 @@ module CarrierWave
25
25
 
26
26
  end
27
27
 
28
- if defined?(Merb)
29
-
30
- CarrierWave.root = Merb.dir_for(:public)
31
- Merb::BootLoader.before_app_loads do
32
- # Setup path for uploaders and load all of them before classes are loaded
33
- Merb.push_path(:uploaders, Merb.root / 'app' / 'uploaders', '*.rb')
34
- Dir.glob(File.join(Merb.load_paths[:uploaders])).each {|f| require f }
35
- end
36
-
37
- elsif defined?(Jets)
28
+ if defined?(Jets)
38
29
 
39
30
  module CarrierWave
40
31
  class Turbine < Jets::Turbine
@@ -84,13 +75,14 @@ elsif defined?(Sinatra)
84
75
  CarrierWave.root = File.join(PADRINO_ROOT, "public")
85
76
  else
86
77
 
87
- CarrierWave.root = if Sinatra::Application.respond_to?(:public_folder)
88
- # Sinatra >= 1.3
89
- Sinatra::Application.public_folder
90
- else
91
- # Sinatra < 1.3
92
- Sinatra::Application.public
93
- end
78
+ CarrierWave.root =
79
+ if Sinatra::Application.respond_to?(:public_folder)
80
+ # Sinatra >= 1.3
81
+ Sinatra::Application.public_folder
82
+ else
83
+ # Sinatra < 1.3
84
+ Sinatra::Application.public
85
+ end
94
86
  end
95
87
  end
96
88