diff options
9 files changed, 63 insertions, 43 deletions
diff --git a/actionpack/test/dispatch/routing_assertions_test.rb b/actionpack/test/dispatch/routing_assertions_test.rb index a8f00af6de..a5198f2f13 100644 --- a/actionpack/test/dispatch/routing_assertions_test.rb +++ b/actionpack/test/dispatch/routing_assertions_test.rb @@ -1,4 +1,3 @@ -<<<<<<< HEAD # frozen_string_literal: true require "abstract_unit" @@ -23,16 +22,16 @@ class RoutingAssertionsTest < ActionController::TestCase engine.routes.draw do resources :books - scope 'secure', :constraints => { :protocol => 'https://' } do - resources :books, :controller => 'secure_books' + scope "secure", constraints: { protocol: "https://" } do + resources :books, controller: "secure_books" end - scope 'block', :constraints => lambda { |r| r.ssl? } do - resources :books, :controller => 'block_books' + scope "block", constraints: lambda { |r| r.ssl? } do + resources :books, controller: "block_books" end - scope 'query', :constraints => lambda { |r| r.params[:use_query] == 'true' } do - resources :books, :controller => 'query_books' + scope "query", constraints: lambda { |r| r.params[:use_query] == "true" } do + resources :books, controller: "query_books" end end @@ -113,43 +112,43 @@ class RoutingAssertionsTest < ActionController::TestCase end def test_assert_recognizes_with_engine - assert_recognizes({ :controller => 'books', :action => 'index' }, '/shelf/books') - assert_recognizes({ :controller => 'books', :action => 'show', :id => '1' }, '/shelf/books/1') + assert_recognizes({ controller: "books", action: "index" }, "/shelf/books") + assert_recognizes({ controller: "books", action: "show", id: "1" }, "/shelf/books/1") end def test_assert_recognizes_with_engine_and_extras - assert_recognizes({ :controller => 'books', :action => 'index', :page => '1' }, '/shelf/books', { :page => '1' }) + assert_recognizes({ controller: "books", action: "index", page: "1" }, "/shelf/books", page: "1") end def test_assert_recognizes_with_engine_and_method - assert_recognizes({ :controller => 'books', :action => 'create' }, { :path => '/shelf/books', :method => :post }) - assert_recognizes({ :controller => 'books', :action => 'update', :id => '1' }, { :path => '/shelf/books/1', :method => :put }) + assert_recognizes({ controller: "books", action: "create" }, { path: "/shelf/books", method: :post }) + assert_recognizes({ controller: "books", action: "update", id: "1" }, { path: "/shelf/books/1", method: :put }) end def test_assert_recognizes_with_engine_and_hash_constraint assert_raise(Assertion) do - assert_recognizes({ :controller => 'secure_books', :action => 'index' }, 'http://test.host/shelf/secure/books') + assert_recognizes({ controller: "secure_books", action: "index" }, "http://test.host/shelf/secure/books") end - assert_recognizes({ :controller => 'secure_books', :action => 'index', :protocol => 'https://' }, 'https://test.host/shelf/secure/books') + assert_recognizes({ controller: "secure_books", action: "index", protocol: "https://" }, "https://test.host/shelf/secure/books") end def test_assert_recognizes_with_engine_and_block_constraint assert_raise(Assertion) do - assert_recognizes({ :controller => 'block_books', :action => 'index' }, 'http://test.host/shelf/block/books') + assert_recognizes({ controller: "block_books", action: "index" }, "http://test.host/shelf/block/books") end - assert_recognizes({ :controller => 'block_books', :action => 'index' }, 'https://test.host/shelf/block/books') + assert_recognizes({ controller: "block_books", action: "index" }, "https://test.host/shelf/block/books") end def test_assert_recognizes_with_engine_and_query_constraint assert_raise(Assertion) do - assert_recognizes({ :controller => 'query_books', :action => 'index', :use_query => 'false' }, '/shelf/query/books', { :use_query => 'false' }) + assert_recognizes({ controller: "query_books", action: "index", use_query: "false" }, "/shelf/query/books", use_query: "false") end - assert_recognizes({ :controller => 'query_books', :action => 'index', :use_query => 'true' }, '/shelf/query/books', { :use_query => 'true' }) + assert_recognizes({ controller: "query_books", action: "index", use_query: "true" }, "/shelf/query/books", use_query: "true") end def test_assert_recognizes_raises_message_with_engine err = assert_raise(Assertion) do - assert_recognizes({ :controller => 'secure_books', :action => 'index' }, 'http://test.host/shelf/secure/books', {}, "This is a really bad msg") + assert_recognizes({ controller: "secure_books", action: "index" }, "http://test.host/shelf/secure/books", {}, "This is a really bad msg") end assert_match err.message, "This is a really bad msg" diff --git a/activemodel/CHANGELOG.md b/activemodel/CHANGELOG.md index 82e3a7f4dd..794744c646 100644 --- a/activemodel/CHANGELOG.md +++ b/activemodel/CHANGELOG.md @@ -1,3 +1,7 @@ +* Execute `ConfirmationValidator` validation when `_confirmation`'s value is `false`. + + *bogdanvlviv* + * Allow passing a Proc or Symbol to length validator options. *Matt Rohrer* diff --git a/activemodel/lib/active_model/validations/confirmation.rb b/activemodel/lib/active_model/validations/confirmation.rb index 0abec56b68..1b5d5b09ab 100644 --- a/activemodel/lib/active_model/validations/confirmation.rb +++ b/activemodel/lib/active_model/validations/confirmation.rb @@ -9,7 +9,7 @@ module ActiveModel end def validate_each(record, attribute, value) - if (confirmed = record.send("#{attribute}_confirmation")) + unless (confirmed = record.send("#{attribute}_confirmation")).nil? unless confirmation_value_equal?(record, attribute, value, confirmed) human_attribute_name = record.class.human_attribute_name(attribute) record.errors.add(:"#{attribute}_confirmation", :confirmation, options.except(:case_sensitive).merge!(attribute: human_attribute_name)) diff --git a/activemodel/test/cases/validations/confirmation_validation_test.rb b/activemodel/test/cases/validations/confirmation_validation_test.rb index e84415a868..8b2c65289b 100644 --- a/activemodel/test/cases/validations/confirmation_validation_test.rb +++ b/activemodel/test/cases/validations/confirmation_validation_test.rb @@ -37,6 +37,19 @@ class ConfirmationValidationTest < ActiveModel::TestCase assert t.valid? end + def test_validates_confirmation_of_with_boolean_attribute + Topic.validates_confirmation_of(:approved) + + t = Topic.new(approved: true, approved_confirmation: nil) + assert t.valid? + + t.approved_confirmation = false + assert t.invalid? + + t.approved_confirmation = true + assert t.valid? + end + def test_validates_confirmation_of_for_ruby_class Person.validates_confirmation_of :karma diff --git a/activerecord/lib/active_record/associations/preloader/association.rb b/activerecord/lib/active_record/associations/preloader/association.rb index b0c41c7d5f..e77761692d 100644 --- a/activerecord/lib/active_record/associations/preloader/association.rb +++ b/activerecord/lib/active_record/associations/preloader/association.rb @@ -17,8 +17,14 @@ module ActiveRecord end def run(preloader) - associated_records_by_owner(preloader) do |owner, records| - associate_records_to_owner(owner, records) + records = load_records do |record| + owner = owners_by_key[convert_key(record[association_key_name])] + association = owner.association(reflection.name) + association.set_inverse_instance(record) + end + + owners.each do |owner| + associate_records_to_owner(owner, records[convert_key(owner[owner_key_name])] || []) end end @@ -33,18 +39,6 @@ module ActiveRecord reflection.join_foreign_key end - def associated_records_by_owner(preloader) - records = load_records do |record| - owner = owners_by_key[convert_key(record[association_key_name])] - association = owner.association(reflection.name) - association.set_inverse_instance(record) - end - - owners.each_with_object({}) do |owner, result| - yield(owner, records[convert_key(owner[owner_key_name])] || []) - end - end - def associate_records_to_owner(owner, records) raise NotImplementedError end diff --git a/activerecord/lib/active_record/associations/preloader/through_association.rb b/activerecord/lib/active_record/associations/preloader/through_association.rb index 1bb7e98231..b1813ba66b 100644 --- a/activerecord/lib/active_record/associations/preloader/through_association.rb +++ b/activerecord/lib/active_record/associations/preloader/through_association.rb @@ -12,7 +12,7 @@ module ActiveRecord reflection.source_reflection end - def associated_records_by_owner(preloader) + def run(preloader) already_loaded = owners.first.association(through_reflection.name).loaded? through_scope = through_scope() reflection_scope = target_reflection_scope @@ -43,7 +43,7 @@ module ActiveRecord result.sort_by! { |rhs| preload_index[rhs] } if reflection_scope.order_values.any? result.uniq! if reflection_scope.distinct_value end - yield(owner, result) + associate_records_to_owner(owner, result) end end diff --git a/activestorage/lib/active_storage/service/azure_storage_service.rb b/activestorage/lib/active_storage/service/azure_storage_service.rb index 27dd192ce6..f3877ad9c9 100644 --- a/activestorage/lib/active_storage/service/azure_storage_service.rb +++ b/activestorage/lib/active_storage/service/azure_storage_service.rb @@ -28,7 +28,7 @@ module ActiveStorage end end - def download(key) + def download(key, &block) if block_given? instrument :streaming_download, key do stream(key, &block) @@ -108,15 +108,15 @@ module ActiveStorage end # Reads the object for the given key in chunks, yielding each to the block. - def stream(key, options = {}, &block) + def stream(key) blob = blob_for(key) chunk_size = 5.megabytes offset = 0 while offset < blob.properties[:content_length] - _, io = blobs.get_blob(container, key, start_range: offset, end_range: offset + chunk_size - 1) - yield io + _, chunk = blobs.get_blob(container, key, start_range: offset, end_range: offset + chunk_size - 1) + yield chunk.force_encoding(Encoding::BINARY) offset += chunk_size end end diff --git a/activestorage/lib/active_storage/service/s3_service.rb b/activestorage/lib/active_storage/service/s3_service.rb index 3e93cdd072..958b172efb 100644 --- a/activestorage/lib/active_storage/service/s3_service.rb +++ b/activestorage/lib/active_storage/service/s3_service.rb @@ -26,7 +26,7 @@ module ActiveStorage end end - def download(key) + def download(key, &block) if block_given? instrument :streaming_download, key do stream(key, &block) @@ -85,14 +85,14 @@ module ActiveStorage end # Reads the object for the given key in chunks, yielding each to the block. - def stream(key, options = {}, &block) + def stream(key, &block) object = object_for(key) chunk_size = 5.megabytes offset = 0 while offset < object.content_length - yield object.read(options.merge(range: "bytes=#{offset}-#{offset + chunk_size - 1}")) + yield object.get(range: "bytes=#{offset}-#{offset + chunk_size - 1}").body.read.force_encoding(Encoding::BINARY) offset += chunk_size end end diff --git a/activestorage/test/service/shared_service_tests.rb b/activestorage/test/service/shared_service_tests.rb index a9e1cb6ce9..ade91ab89a 100644 --- a/activestorage/test/service/shared_service_tests.rb +++ b/activestorage/test/service/shared_service_tests.rb @@ -50,6 +50,16 @@ module ActiveStorage::Service::SharedServiceTests assert_equal FIXTURE_DATA, @service.download(FIXTURE_KEY) end + test "downloading in chunks" do + chunks = [] + + @service.download(FIXTURE_KEY) do |chunk| + chunks << chunk + end + + assert_equal [ FIXTURE_DATA ], chunks + end + test "existing" do assert @service.exist?(FIXTURE_KEY) assert_not @service.exist?(FIXTURE_KEY + "nonsense") |