lib/paperclip.rb in paperclip-2.4.5 vs lib/paperclip.rb in paperclip-2.5.0

- old
+ new

@@ -26,11 +26,10 @@ # See the +has_attached_file+ documentation for more details. require 'erb' require 'digest' require 'tempfile' -require 'paperclip/options' require 'paperclip/version' require 'paperclip/upfile' require 'paperclip/iostream' require 'paperclip/geometry' require 'paperclip/processor' @@ -48,11 +47,11 @@ # The base module that gets included in ActiveRecord::Base. See the # documentation for Paperclip::ClassMethods for more useful information. module Paperclip class << self - # Provides configurability to Paperclip. There are a number of options available, such as: + # Provides configurability to Paperclip. The options available are: # * whiny: Will raise an error if Paperclip cannot process thumbnails of # an uploaded image. Defaults to true. # * log: Logs progress to the Rails log. Uses ActiveRecord's logger, so honors # log levels, etc. Defaults to true. # * command_path: Defines the path at which to find the command line @@ -138,12 +137,15 @@ end # Find all instances of the given Active Record model +klass+ with attachment +name+. # This method is used by the refresh rake tasks. def each_instance_with_attachment(klass, name) - class_for(klass).find(:all, :order => 'id').each do |instance| - yield(instance) if instance.send(:"#{name}?") + unscope_method = class_for(klass).respond_to?(:unscoped) ? :unscoped : :with_exclusive_scope + class_for(klass).send(unscope_method) do + class_for(klass).find(:all, :order => 'id').each do |instance| + yield(instance) if instance.send(:"#{name}?") + end end end # Log a paperclip-specific line. This will logs to STDOUT # by default. Set Paperclip.options[:log] to false to turn off. @@ -175,13 +177,13 @@ class_name.split('::').inject(Object) do |klass, partial_class_name| klass.const_defined?(partial_class_name) ? klass.const_get(partial_class_name, false) : klass.const_missing(partial_class_name) end end rescue ArgumentError => e - # Sadly, we need to capture ArguementError here because Rails 2.3.x - # Active Support dependency's management will try to the constant inherited - # from Object, and fail misably with "Object is not missing constant X" error + # Sadly, we need to capture ArgumentError here because Rails 2.3.x + # ActiveSupport dependency management will try to the constant inherited + # from Object, and fail miserably with "Object is not missing constant X" error # https://github.com/rails/rails/blob/v2.3.12/activesupport/lib/active_support/dependencies.rb#L124 if e.message =~ /is not missing constant/ raise NameError, "uninitialized constant #{class_name}" else raise e @@ -189,11 +191,11 @@ end def check_for_url_clash(name,url,klass) @names_url ||= {} default_url = url || Attachment.default_options[:url] - if @names_url[name] && @names_url[name][:url] == default_url && @names_url[name][:class] != klass + if @names_url[name] && @names_url[name][:url] == default_url && @names_url[name][:class] != klass && @names_url[name][:url] !~ /:class/ log("Duplicate URL for #{name} with #{default_url}. This will clash with attachment defined in #{@names_url[name][:class]} class") end @names_url[name] = {:url => default_url, :class => klass} end @@ -262,10 +264,13 @@ # * +default_style+: The thumbnail style that will be used by default URLs. # Defaults to +original+. # has_attached_file :avatar, :styles => { :normal => "100x100#" }, # :default_style => :normal # user.avatar.url # => "/avatars/23/normal_me.png" + # * +keep_old_files+: Keep the existing attachment files (original + resized) from + # being automatically deleted when an attachment is cleared or updated. + # Defaults to +false+.# # * +whiny+: Will raise an error if Paperclip cannot post_process an uploaded file due # to a command line error. This will override the global setting for this attachment. # Defaults to true. This option used to be called :whiny_thumbanils, but this is # deprecated. # * +convert_options+: When creating thumbnails, use this free-form options @@ -288,15 +293,15 @@ # :styles for compatibility with future versions. # NOTE: Strings supplied to :convert_options are split on space in order to undergo # shell quoting for safety. If your options require a space, please pre-split them # and pass an array to :convert_options instead. # * +storage+: Chooses the storage backend where the files will be stored. The current - # choices are :filesystem and :s3. The default is :filesystem. Make sure you read the - # documentation for Paperclip::Storage::Filesystem and Paperclip::Storage::S3 + # choices are :filesystem, :fog and :s3. The default is :filesystem. Make sure you read the + # documentation for Paperclip::Storage::Filesystem, Paperclip::Storage::Fog and Paperclip::Storage::S3 # for backend-specific options. # - # It's also possible for you to dynamicly define your interpolation string for :url, + # It's also possible for you to dynamically define your interpolation string for :url, # :default_url, and :path in your model by passing a method name as a symbol as a argument # for your has_attached_file definition: # # class Person # has_attached_file :avatar, :default_url => :default_url_by_gender @@ -314,10 +319,12 @@ if respond_to?(:class_attribute) self.attachment_definitions = {} else write_inheritable_attribute(:attachment_definitions, {}) end + else + self.attachment_definitions = self.attachment_definitions.dup end attachment_definitions[name] = {:validations => []}.merge(options) Paperclip.classes_with_attachments << self.name Paperclip.check_for_url_clash(name,attachment_definitions[name][:url],self.name) @@ -351,12 +358,12 @@ # possible options are: # * +in+: a Range of bytes (i.e. +1..1.megabyte+), # * +less_than+: equivalent to :in => 0..options[:less_than] # * +greater_than+: equivalent to :in => options[:greater_than]..Infinity # * +message+: error message to display, use :min and :max as replacements - # * +if+: A lambda or name of a method on the instance. Validation will only - # be run is this lambda or method returns true. + # * +if+: A lambda or name of an instance method. Validation will only + # be run if this lambda or method returns true. # * +unless+: Same as +if+ but validates if lambda or method returns false. def validates_attachment_size name, options = {} min = options[:greater_than] || (options[:in] && options[:in].first) || 0 max = options[:less_than] || (options[:in] && options[:in].last) || (1.0/0) range = (min..max) @@ -380,18 +387,18 @@ attachment_definitions[name][:whiny_thumbnails] = true end # Places ActiveRecord-style validations on the presence of a file. # Options: - # * +if+: A lambda or name of a method on the instance. Validation will only - # be run is this lambda or method returns true. + # * +if+: A lambda or name of an instance method. Validation will only + # be run if this lambda or method returns true. # * +unless+: Same as +if+ but validates if lambda or method returns false. def validates_attachment_presence name, options = {} message = options[:message] || :empty validates_each :"#{name}_file_name" do |record, attr, value| - if_clause_passed = options[:if].nil? || (options[:if].call(record) != false) - unless_clause_passed = options[:unless].nil? || (!!options[:unless].call(record) == false) + if_clause_passed = options[:if].nil? || (options[:if].respond_to?(:call) ? options[:if].call(record) != false : record.send(options[:if])) + unless_clause_passed = options[:unless].nil? || (options[:unless].respond_to?(:call) ? !!options[:unless].call(record) == false : !record.send(options[:unless])) if if_clause_passed && unless_clause_passed && value.blank? record.errors.add(name, message) record.errors.add("#{name}_file_name", message) end end @@ -399,16 +406,16 @@ # Places ActiveRecord-style validations on the content type of the file # assigned. The possible options are: # * +content_type+: Allowed content types. Can be a single content type # or an array. Each type can be a String or a Regexp. It should be - # noted that Internet Explorer upload files with content_types that you + # noted that Internet Explorer uploads files with content_types that you # may not expect. For example, JPEG images are given image/pjpeg and # PNGs are image/x-png, so keep that in mind when determining how you # match. Allows all by default. # * +message+: The message to display when the uploaded file has an invalid # content type. - # * +if+: A lambda or name of a method on the instance. Validation will only + # * +if+: A lambda or name of an instance method. Validation will only # be run is this lambda or method returns true. # * +unless+: Same as +if+ but validates if lambda or method returns false. # NOTE: If you do not specify an [attachment]_content_type field on your # model, content_type validation will work _ONLY upon assignment_ and # re-validation after the instance has been reloaded will always succeed.