diff options
-rw-r--r-- | activerecord/lib/active_record/attribute_methods/before_type_cast.rb | 6 | ||||
-rw-r--r-- | activerecord/lib/active_record/attribute_methods/dirty.rb | 4 | ||||
-rw-r--r-- | activerecord/lib/active_record/attribute_methods/read.rb | 2 | ||||
-rw-r--r-- | activerecord/lib/active_record/attribute_methods/write.rb | 4 | ||||
-rw-r--r-- | activerecord/lib/active_record/core.rb | 3 | ||||
-rw-r--r-- | activerecord/lib/active_record/persistence.rb | 6 | ||||
-rw-r--r-- | activerecord/lib/active_record/relation.rb | 4 | ||||
-rw-r--r-- | activerecord/lib/active_record/relation/query_methods.rb | 23 | ||||
-rw-r--r-- | activerecord/lib/active_record/transactions.rb | 4 | ||||
-rw-r--r-- | activestorage/CHANGELOG.md | 4 | ||||
-rw-r--r-- | activestorage/app/models/active_storage/variation.rb | 2 | ||||
-rw-r--r-- | activestorage/lib/active_storage/engine.rb | 2 | ||||
-rw-r--r-- | activestorage/test/fixtures/files/colors.bmp | bin | 0 -> 2810 bytes | |||
-rw-r--r-- | activestorage/test/models/variant_test.rb | 19 | ||||
-rw-r--r-- | guides/source/layouts_and_rendering.md | 2 |
15 files changed, 51 insertions, 34 deletions
diff --git a/activerecord/lib/active_record/attribute_methods/before_type_cast.rb b/activerecord/lib/active_record/attribute_methods/before_type_cast.rb index affcf2a4db..3d917ec9b1 100644 --- a/activerecord/lib/active_record/attribute_methods/before_type_cast.rb +++ b/activerecord/lib/active_record/attribute_methods/before_type_cast.rb @@ -46,7 +46,7 @@ module ActiveRecord # task.read_attribute_before_type_cast('completed_on') # => "2012-10-21" # task.read_attribute_before_type_cast(:completed_on) # => "2012-10-21" def read_attribute_before_type_cast(attr_name) - sync_with_transaction_state + sync_with_transaction_state if @transaction_state&.finalized? @attributes[attr_name.to_s].value_before_type_cast end @@ -61,7 +61,7 @@ module ActiveRecord # task.attributes_before_type_cast # # => {"id"=>nil, "title"=>nil, "is_done"=>true, "completed_on"=>"2012-10-21", "created_at"=>nil, "updated_at"=>nil} def attributes_before_type_cast - sync_with_transaction_state + sync_with_transaction_state if @transaction_state&.finalized? @attributes.values_before_type_cast end @@ -73,7 +73,7 @@ module ActiveRecord end def attribute_came_from_user?(attribute_name) - sync_with_transaction_state + sync_with_transaction_state if @transaction_state&.finalized? @attributes[attribute_name].came_from_user? end end diff --git a/activerecord/lib/active_record/attribute_methods/dirty.rb b/activerecord/lib/active_record/attribute_methods/dirty.rb index 942fe48635..444568562b 100644 --- a/activerecord/lib/active_record/attribute_methods/dirty.rb +++ b/activerecord/lib/active_record/attribute_methods/dirty.rb @@ -157,12 +157,12 @@ module ActiveRecord private def mutations_from_database - sync_with_transaction_state + sync_with_transaction_state if @transaction_state&.finalized? super end def mutations_before_last_save - sync_with_transaction_state + sync_with_transaction_state if @transaction_state&.finalized? super end diff --git a/activerecord/lib/active_record/attribute_methods/read.rb b/activerecord/lib/active_record/attribute_methods/read.rb index 84b1ec2fea..409a150e56 100644 --- a/activerecord/lib/active_record/attribute_methods/read.rb +++ b/activerecord/lib/active_record/attribute_methods/read.rb @@ -39,7 +39,7 @@ module ActiveRecord # This method exists to avoid the expensive primary_key check internally, without # breaking compatibility with the read_attribute API def _read_attribute(attr_name, &block) # :nodoc - sync_with_transaction_state + sync_with_transaction_state if @transaction_state&.finalized? @attributes.fetch_value(attr_name.to_s, &block) end diff --git a/activerecord/lib/active_record/attribute_methods/write.rb b/activerecord/lib/active_record/attribute_methods/write.rb index d1cfe43bb2..6a21643884 100644 --- a/activerecord/lib/active_record/attribute_methods/write.rb +++ b/activerecord/lib/active_record/attribute_methods/write.rb @@ -43,14 +43,14 @@ module ActiveRecord # This method exists to avoid the expensive primary_key check internally, without # breaking compatibility with the write_attribute API def _write_attribute(attr_name, value) # :nodoc: - sync_with_transaction_state + sync_with_transaction_state if @transaction_state&.finalized? @attributes.write_from_user(attr_name.to_s, value) value end private def write_attribute_without_type_cast(attr_name, value) - sync_with_transaction_state + sync_with_transaction_state if @transaction_state&.finalized? @attributes.write_cast_value(attr_name.to_s, value) value end diff --git a/activerecord/lib/active_record/core.rb b/activerecord/lib/active_record/core.rb index 04b21b4d00..b9046fcc1a 100644 --- a/activerecord/lib/active_record/core.rb +++ b/activerecord/lib/active_record/core.rb @@ -101,7 +101,6 @@ module ActiveRecord # environment where dumping schema is rarely needed. mattr_accessor :dump_schema_after_migration, instance_writer: false, default: true - mattr_accessor :database_selector, instance_writer: false ## # :singleton-method: # Specifies which database schemas to dump when calling db:structure:dump. @@ -466,7 +465,7 @@ module ActiveRecord # Returns +true+ if the attributes hash has been frozen. def frozen? - sync_with_transaction_state + sync_with_transaction_state if @transaction_state&.finalized? @attributes.frozen? end diff --git a/activerecord/lib/active_record/persistence.rb b/activerecord/lib/active_record/persistence.rb index 8bade8cd28..bd572486c8 100644 --- a/activerecord/lib/active_record/persistence.rb +++ b/activerecord/lib/active_record/persistence.rb @@ -423,20 +423,20 @@ module ActiveRecord # Returns true if this object hasn't been saved yet -- that is, a record # for the object doesn't exist in the database yet; otherwise, returns false. def new_record? - sync_with_transaction_state + sync_with_transaction_state if @transaction_state&.finalized? @new_record end # Returns true if this object has been destroyed, otherwise returns false. def destroyed? - sync_with_transaction_state + sync_with_transaction_state if @transaction_state&.finalized? @destroyed end # Returns true if the record is persisted, i.e. it's not a new record and it was # not destroyed, otherwise returns false. def persisted? - sync_with_transaction_state + sync_with_transaction_state if @transaction_state&.finalized? !(@new_record || @destroyed) end diff --git a/activerecord/lib/active_record/relation.rb b/activerecord/lib/active_record/relation.rb index ab24f67a6d..add95f6a0a 100644 --- a/activerecord/lib/active_record/relation.rb +++ b/activerecord/lib/active_record/relation.rb @@ -553,8 +553,8 @@ module ActiveRecord # # => ActiveRecord::ActiveRecordError: delete_all doesn't support distinct def delete_all invalid_methods = INVALID_METHODS_FOR_DELETE_ALL.select do |method| - value = get_value(method) - SINGLE_VALUE_METHODS.include?(method) ? value : value.any? + value = @values[method] + method == :distinct ? value : value&.any? end if invalid_methods.any? raise ActiveRecordError.new("delete_all doesn't support #{invalid_methods.join(', ')}") diff --git a/activerecord/lib/active_record/relation/query_methods.rb b/activerecord/lib/active_record/relation/query_methods.rb index 90b5e9a118..5d3cea6741 100644 --- a/activerecord/lib/active_record/relation/query_methods.rb +++ b/activerecord/lib/active_record/relation/query_methods.rb @@ -67,11 +67,13 @@ module ActiveRecord end class_eval <<-CODE, __FILE__, __LINE__ + 1 def #{method_name} # def includes_values - get_value(#{name.inspect}) # get_value(:includes) + default = DEFAULT_VALUES[:#{name}] # default = DEFAULT_VALUES[:includes] + @values.fetch(:#{name}, default) # @values.fetch(:includes, default) end # end def #{method_name}=(value) # def includes_values=(value) - set_value(#{name.inspect}, value) # set_value(:includes, value) + assert_mutability! # assert_mutability! + @values[:#{name}] = value # @values[:includes] = value end # end CODE end @@ -417,7 +419,8 @@ module ActiveRecord if !VALID_UNSCOPING_VALUES.include?(scope) raise ArgumentError, "Called unscope() with invalid unscoping argument ':#{scope}'. Valid arguments are :#{VALID_UNSCOPING_VALUES.to_a.join(", :")}." end - set_value(scope, DEFAULT_VALUES[scope]) + assert_mutability! + @values[scope] = DEFAULT_VALUES[scope] when Hash scope.each do |key, target_value| if key != :where @@ -1005,17 +1008,6 @@ module ActiveRecord end private - # Returns a relation value with a given name - def get_value(name) - @values.fetch(name, DEFAULT_VALUES[name]) - end - - # Sets the relation value with the given name - def set_value(name, value) - assert_mutability! - @values[name] = value - end - def assert_mutability! raise ImmutableRelation if @loaded raise ImmutableRelation if defined?(@arel) && @arel @@ -1316,7 +1308,8 @@ module ActiveRecord def structurally_incompatible_values_for_or(other) values = other.values STRUCTURAL_OR_METHODS.reject do |method| - get_value(method) == values.fetch(method, DEFAULT_VALUES[method]) + default = DEFAULT_VALUES[method] + @values.fetch(method, default) == values.fetch(method, default) end end diff --git a/activerecord/lib/active_record/transactions.rb b/activerecord/lib/active_record/transactions.rb index ea288456b9..9f52734e00 100644 --- a/activerecord/lib/active_record/transactions.rb +++ b/activerecord/lib/active_record/transactions.rb @@ -365,7 +365,7 @@ module ActiveRecord status = nil self.class.transaction do unless has_transactional_callbacks? - sync_with_transaction_state + sync_with_transaction_state if @transaction_state&.finalized? @transaction_state = self.class.connection.transaction_state end remember_transaction_record_state @@ -479,7 +479,7 @@ module ActiveRecord # the TransactionState, and rolls back or commits the Active Record object # as appropriate. def sync_with_transaction_state - if (transaction_state = @transaction_state)&.finalized? + if transaction_state = @transaction_state if transaction_state.fully_committed? force_clear_transaction_record_state elsif transaction_state.committed? diff --git a/activestorage/CHANGELOG.md b/activestorage/CHANGELOG.md index 54fc949172..d524ecf7d6 100644 --- a/activestorage/CHANGELOG.md +++ b/activestorage/CHANGELOG.md @@ -1,3 +1,7 @@ +* Permit generating variants of BMP images. + + *Younes Serraj* + ## Rails 6.0.0.beta3 (March 11, 2019) ## * No changes. diff --git a/activestorage/app/models/active_storage/variation.rb b/activestorage/app/models/active_storage/variation.rb index 41b5a45f53..45ae71e0ca 100644 --- a/activestorage/app/models/active_storage/variation.rb +++ b/activestorage/app/models/active_storage/variation.rb @@ -40,7 +40,7 @@ class ActiveStorage::Variation end def initialize(transformations) - @transformations = transformations + @transformations = transformations.deep_symbolize_keys end # Accepts a File object, performs the +transformations+ against it, and diff --git a/activestorage/lib/active_storage/engine.rb b/activestorage/lib/active_storage/engine.rb index fc75a8f816..cbb205627e 100644 --- a/activestorage/lib/active_storage/engine.rb +++ b/activestorage/lib/active_storage/engine.rb @@ -33,6 +33,7 @@ module ActiveStorage image/jpeg image/pjpeg image/tiff + image/bmp image/vnd.adobe.photoshop image/vnd.microsoft.icon ) @@ -56,6 +57,7 @@ module ActiveStorage image/jpg image/jpeg image/tiff + image/bmp image/vnd.adobe.photoshop image/vnd.microsoft.icon application/pdf diff --git a/activestorage/test/fixtures/files/colors.bmp b/activestorage/test/fixtures/files/colors.bmp Binary files differnew file mode 100644 index 0000000000..3cc1e8764d --- /dev/null +++ b/activestorage/test/fixtures/files/colors.bmp diff --git a/activestorage/test/models/variant_test.rb b/activestorage/test/models/variant_test.rb index d98935eb9f..6b43923159 100644 --- a/activestorage/test/models/variant_test.rb +++ b/activestorage/test/models/variant_test.rb @@ -4,6 +4,14 @@ require "test_helper" require "database/setup" class ActiveStorage::VariantTest < ActiveSupport::TestCase + test "variations have the same key for different types of the same transformation" do + blob = create_file_blob(filename: "racecar.jpg") + variant_a = blob.variant(resize: "100x100") + variant_b = blob.variant("resize" => "100x100") + + assert_equal variant_a.key, variant_b.key + end + test "resized variation of JPEG blob" do blob = create_file_blob(filename: "racecar.jpg") variant = blob.variant(resize: "100x100").processed @@ -144,6 +152,17 @@ class ActiveStorage::VariantTest < ActiveSupport::TestCase assert_equal 33, image.height end + test "resized variation of BMP blob" do + blob = create_file_blob(filename: "colors.bmp") + variant = blob.variant(resize: "15x15").processed + assert_match(/colors\.bmp/, variant.service_url) + + image = read_image(variant) + assert_equal "BMP", image.type + assert_equal 15, image.width + assert_equal 8, image.height + end + test "optimized variation of GIF blob" do blob = create_file_blob(filename: "image.gif", content_type: "image/gif") diff --git a/guides/source/layouts_and_rendering.md b/guides/source/layouts_and_rendering.md index 2808527141..39935cd2ef 100644 --- a/guides/source/layouts_and_rendering.md +++ b/guides/source/layouts_and_rendering.md @@ -689,7 +689,7 @@ Just like the `:status` option for `render`, `:status` for `redirect_to` accepts #### The Difference Between `render` and `redirect_to` -Sometimes inexperienced developers think of `redirect_to` as a sort of `goto` command, moving execution from one place to another in your Rails code. This is _not_ correct. Your code stops running and waits for a new request for the browser. It just happens that you've told the browser what request it should make next, by sending back an HTTP 302 status code. +Sometimes inexperienced developers think of `redirect_to` as a sort of `goto` command, moving execution from one place to another in your Rails code. This is _not_ correct. Your code stops running and waits for a new request from the browser. It just happens that you've told the browser what request it should make next, by sending back an HTTP 302 status code. Consider these actions to see the difference: |