aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Gemfile1
-rw-r--r--Gemfile.lock1
-rw-r--r--activerecord/CHANGELOG.md14
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract_adapter.rb5
-rw-r--r--activerecord/lib/active_record/sanitization.rb8
-rw-r--r--activerecord/test/cases/finder_test.rb18
-rw-r--r--activestorage/lib/active_storage/downloading.rb12
-rw-r--r--activestorage/lib/active_storage/previewer.rb12
-rw-r--r--activestorage/test/service/mirror_service_test.rb32
-rw-r--r--guides/source/active_storage_overview.md2
-rw-r--r--guides/source/asset_pipeline.md17
-rw-r--r--guides/source/configuring.md5
-rw-r--r--guides/source/security.md5
13 files changed, 95 insertions, 37 deletions
diff --git a/Gemfile b/Gemfile
index 7cb312fbec..18e014e72f 100644
--- a/Gemfile
+++ b/Gemfile
@@ -110,7 +110,6 @@ local_gemfile = File.expand_path(".Gemfile", __dir__)
instance_eval File.read local_gemfile if File.exist? local_gemfile
group :test do
- gem "minitest", "= 5.11.1"
gem "minitest-bisect"
platforms :mri do
diff --git a/Gemfile.lock b/Gemfile.lock
index 97f79a0112..2d4c3e1383 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -533,7 +533,6 @@ DEPENDENCIES
libxml-ruby
listen (>= 3.0.5, < 3.2)
mini_magick
- minitest (= 5.11.1)
minitest-bisect
mocha
mysql2 (>= 0.4.4)
diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md
index af77eaae0e..fd9f2553ff 100644
--- a/activerecord/CHANGELOG.md
+++ b/activerecord/CHANGELOG.md
@@ -1,3 +1,17 @@
+* Fix not expanded problem when passing an Array object as argument to the where method using `composed_of` column.
+
+ ```
+ david_balance = customers(:david).balance
+ Customer.where(balance: [david_balance]).to_sql
+
+ # Before: WHERE `customers`.`balance` = NULL
+ # After : WHERE `customers`.`balance` = 50
+ ```
+
+ Fixes #31723.
+
+ *Yutaro Kanagawa*
+
* Fix `count(:all)` with eager loading and having an order other than the driving table.
Fixes #31783.
diff --git a/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb b/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb
index 7bd54f777e..56a5ea153b 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb
@@ -326,6 +326,11 @@ module ActiveRecord
false
end
+ # Does this adapter support foreign/external tables?
+ def supports_foreign_tables?
+ false
+ end
+
# This is meant to be implemented by the adapters that support extensions
def disable_extension(name)
end
diff --git a/activerecord/lib/active_record/sanitization.rb b/activerecord/lib/active_record/sanitization.rb
index 58da106092..173794b8f4 100644
--- a/activerecord/lib/active_record/sanitization.rb
+++ b/activerecord/lib/active_record/sanitization.rb
@@ -155,10 +155,12 @@ module ActiveRecord
if aggregation = reflect_on_aggregation(attr.to_sym)
mapping = aggregation.mapping
mapping.each do |field_attr, aggregate_attr|
- if mapping.size == 1 && !value.respond_to?(aggregate_attr)
- expanded_attrs[field_attr] = value
+ expanded_attrs[field_attr] = if value.is_a?(Array)
+ value.map { |it| it.send(aggregate_attr) }
+ elsif mapping.size == 1 && !value.respond_to?(aggregate_attr)
+ value
else
- expanded_attrs[field_attr] = value.send(aggregate_attr)
+ value.send(aggregate_attr)
end
end
else
diff --git a/activerecord/test/cases/finder_test.rb b/activerecord/test/cases/finder_test.rb
index c78c13ece3..fabfc4574c 100644
--- a/activerecord/test/cases/finder_test.rb
+++ b/activerecord/test/cases/finder_test.rb
@@ -868,6 +868,24 @@ class FinderTest < ActiveRecord::TestCase
assert_equal customers(:david), found_customer
end
+ def test_hash_condition_find_with_aggregate_having_three_mapping_array
+ david_address = customers(:david).address
+ zaphod_address = customers(:zaphod).address
+ assert_kind_of Address, david_address
+ assert_kind_of Address, zaphod_address
+ found_customers = Customer.where(address: [david_address, zaphod_address])
+ assert_equal [customers(:david), customers(:zaphod)], found_customers
+ end
+
+ def test_hash_condition_find_with_aggregate_having_one_mapping_array
+ david_balance = customers(:david).balance
+ zaphod_balance = customers(:zaphod).balance
+ assert_kind_of Money, david_balance
+ assert_kind_of Money, zaphod_balance
+ found_customers = Customer.where(balance: [david_balance, zaphod_balance])
+ assert_equal [customers(:david), customers(:zaphod)], found_customers
+ end
+
def test_hash_condition_find_with_aggregate_attribute_having_same_name_as_field_and_key_value_being_aggregate
gps_location = customers(:david).gps_location
assert_kind_of GpsLocation, gps_location
diff --git a/activestorage/lib/active_storage/downloading.rb b/activestorage/lib/active_storage/downloading.rb
index 295289c1e7..f2a1fffdcb 100644
--- a/activestorage/lib/active_storage/downloading.rb
+++ b/activestorage/lib/active_storage/downloading.rb
@@ -7,12 +7,22 @@ module ActiveStorage
private
# Opens a new tempfile in #tempdir and copies blob data into it. Yields the tempfile.
def download_blob_to_tempfile #:doc:
- Tempfile.open([ "ActiveStorage", blob.filename.extension_with_delimiter ], tempdir) do |file|
+ open_tempfile_for_blob do |file|
download_blob_to file
yield file
end
end
+ def open_tempfile_for_blob
+ tempfile = Tempfile.open([ "ActiveStorage", blob.filename.extension_with_delimiter ], tempdir)
+
+ begin
+ yield tempfile
+ ensure
+ tempfile.close!
+ end
+ end
+
# Efficiently downloads blob data into the given file.
def download_blob_to(file) #:doc:
file.binmode
diff --git a/activestorage/lib/active_storage/previewer.rb b/activestorage/lib/active_storage/previewer.rb
index dacab1e7df..cf19987d72 100644
--- a/activestorage/lib/active_storage/previewer.rb
+++ b/activestorage/lib/active_storage/previewer.rb
@@ -44,13 +44,23 @@ module ActiveStorage
# The output tempfile is opened in the directory returned by ActiveStorage::Downloading#tempdir.
def draw(*argv) #:doc:
ActiveSupport::Notifications.instrument("preview.active_storage") do
- Tempfile.open("ActiveStorage", tempdir) do |file|
+ open_tempfile_for_drawing do |file|
capture(*argv, to: file)
yield file
end
end
end
+ def open_tempfile_for_drawing
+ tempfile = Tempfile.open("ActiveStorage", tempdir)
+
+ begin
+ yield tempfile
+ ensure
+ tempfile.close!
+ end
+ end
+
def capture(*argv, to:)
to.binmode
IO.popen(argv, err: File::NULL) { |out| IO.copy_stream(out, to) }
diff --git a/activestorage/test/service/mirror_service_test.rb b/activestorage/test/service/mirror_service_test.rb
index 40476d636e..87306644c5 100644
--- a/activestorage/test/service/mirror_service_test.rb
+++ b/activestorage/test/service/mirror_service_test.rb
@@ -19,11 +19,16 @@ class ActiveStorage::Service::MirrorServiceTest < ActiveSupport::TestCase
test "uploading to all services" do
begin
- data = "Something else entirely!"
- key = upload(data, to: @service)
+ key = SecureRandom.base58(24)
+ data = "Something else entirely!"
+ io = StringIO.new(data)
+ checksum = Digest::MD5.base64digest(data)
- assert_equal data, SERVICE.primary.download(key)
- SERVICE.mirrors.each do |mirror|
+ @service.upload key, io.tap(&:read), checksum: checksum
+ assert_predicate io, :eof?
+
+ assert_equal data, @service.primary.download(key)
+ @service.mirrors.each do |mirror|
assert_equal data, mirror.download(key)
end
ensure
@@ -32,14 +37,18 @@ class ActiveStorage::Service::MirrorServiceTest < ActiveSupport::TestCase
end
test "downloading from primary service" do
- data = "Something else entirely!"
- key = upload(data, to: SERVICE.primary)
+ key = SecureRandom.base58(24)
+ data = "Something else entirely!"
+ checksum = Digest::MD5.base64digest(data)
+
+ @service.primary.upload key, StringIO.new(data), checksum: checksum
assert_equal data, @service.download(key)
end
test "deleting from all services" do
@service.delete FIXTURE_KEY
+
assert_not SERVICE.primary.exist?(FIXTURE_KEY)
SERVICE.mirrors.each do |mirror|
assert_not mirror.exist?(FIXTURE_KEY)
@@ -50,17 +59,8 @@ class ActiveStorage::Service::MirrorServiceTest < ActiveSupport::TestCase
filename = ActiveStorage::Filename.new("test.txt")
freeze_time do
- assert_equal SERVICE.primary.url(FIXTURE_KEY, expires_in: 2.minutes, disposition: :inline, filename: filename, content_type: "text/plain"),
+ assert_equal @service.primary.url(FIXTURE_KEY, expires_in: 2.minutes, disposition: :inline, filename: filename, content_type: "text/plain"),
@service.url(FIXTURE_KEY, expires_in: 2.minutes, disposition: :inline, filename: filename, content_type: "text/plain")
end
end
-
- private
- def upload(data, to:)
- SecureRandom.base58(24).tap do |key|
- io = StringIO.new(data).tap(&:read)
- @service.upload key, io, checksum: Digest::MD5.base64digest(data)
- assert_predicate io, :eof?
- end
- end
end
diff --git a/guides/source/active_storage_overview.md b/guides/source/active_storage_overview.md
index d9f5aa8385..97c56dfd93 100644
--- a/guides/source/active_storage_overview.md
+++ b/guides/source/active_storage_overview.md
@@ -175,7 +175,7 @@ google:
Add the [`google-cloud-storage`](https://github.com/GoogleCloudPlatform/google-cloud-ruby/tree/master/google-cloud-storage) gem to your `Gemfile`:
```ruby
-gem "google-cloud-storage", "~> 1.3", require: false
+gem "google-cloud-storage", "~> 1.8", require: false
```
### Mirror Service
diff --git a/guides/source/asset_pipeline.md b/guides/source/asset_pipeline.md
index e6d5aed135..618896d458 100644
--- a/guides/source/asset_pipeline.md
+++ b/guides/source/asset_pipeline.md
@@ -22,8 +22,7 @@ The asset pipeline provides a framework to concatenate and minify or compress
JavaScript and CSS assets. It also adds the ability to write these assets in
other languages and pre-processors such as CoffeeScript, Sass and ERB.
It allows assets in your application to be automatically combined with assets
-from other gems. For example, jquery-rails includes a copy of jquery.js
-and enables AJAX features in Rails.
+from other gems.
The asset pipeline is implemented by the
[sprockets-rails](https://github.com/rails/sprockets-rails) gem,
@@ -1205,10 +1204,10 @@ Adding Assets to Your Gems
Assets can also come from external sources in the form of gems.
-A good example of this is the `jquery-rails` gem which comes with Rails as the
-standard JavaScript library gem. This gem contains an engine class which
-inherits from `Rails::Engine`. By doing this, Rails is informed that the
-directory for this gem may contain assets and the `app/assets`, `lib/assets` and
+A good example of this is the `jquery-rails` gem.
+This gem contains an engine class which inherits from `Rails::Engine`.
+By doing this, Rails is informed that the directory for this
+gem may contain assets and the `app/assets`, `lib/assets` and
`vendor/assets` directories of this engine are added to the search path of
Sprockets.
@@ -1244,11 +1243,7 @@ moving the files from `public/` to the new locations. See [Asset
Organization](#asset-organization) above for guidance on the correct locations
for different file types.
-Next will be avoiding duplicate JavaScript files. Since jQuery is the default
-JavaScript library from Rails 3.1 onwards, you don't need to copy `jquery.js`
-into `app/assets` and it will be included automatically.
-
-The third is updating the various environment files with the correct default
+Next is updating the various environment files with the correct default
options.
In `application.rb`:
diff --git a/guides/source/configuring.md b/guides/source/configuring.md
index 36c2fdb0b8..a0bf6046da 100644
--- a/guides/source/configuring.md
+++ b/guides/source/configuring.md
@@ -462,7 +462,10 @@ The schema dumper adds one additional configuration option:
config.action_dispatch.default_headers = {
'X-Frame-Options' => 'SAMEORIGIN',
'X-XSS-Protection' => '1; mode=block',
- 'X-Content-Type-Options' => 'nosniff'
+ 'X-Content-Type-Options' => 'nosniff',
+ 'X-Download-Options' => 'noopen',
+ 'X-Permitted-Cross-Domain-Policies' => 'none',
+ 'Referrer-Policy' => 'strict-origin-when-cross-origin'
}
```
diff --git a/guides/source/security.md b/guides/source/security.md
index 724d952d4e..74256c7b84 100644
--- a/guides/source/security.md
+++ b/guides/source/security.md
@@ -1070,7 +1070,10 @@ Every HTTP response from your Rails application receives the following default s
config.action_dispatch.default_headers = {
'X-Frame-Options' => 'SAMEORIGIN',
'X-XSS-Protection' => '1; mode=block',
- 'X-Content-Type-Options' => 'nosniff'
+ 'X-Content-Type-Options' => 'nosniff',
+ 'X-Download-Options' => 'noopen',
+ 'X-Permitted-Cross-Domain-Policies' => 'none',
+ 'Referrer-Policy' => 'strict-origin-when-cross-origin'
}
```