To assert the expected number of queries are made, Rails internally uses
`assert_queries` and `assert_no_queries`. These assertions can be
useful in applications as well.
By extracting these assertions to a module, the assertions can be
included where required.
These assertions are added to `ActiveSupport::TestCase` when
ActiveRecord is defined.
ActiveStorage, ActionView and ActionText are using this module now as
well, instead of duplicating the implementation.
The internal ActiveRecord::TestCase, used for testing ActiveRecord,
implements these assertions as well. However, these are slighlty more
advanced/complex and use the SQLCounter class. To keep things simple,
for now this implementation isn't used.
Add guidance to the Association Basics and `.belongs_to` method
documentation to encourage the renaming of a model's Ruby class to
coincide with updates to the existing data in the database.
Since Action Text and Active Storage rely on polymorphic associations,
add similar warnings to their guides.
Co-authored-by: Petrik de Heus <petrik@deheus.net>
Co-authored-by: Stephen Hanson <s.hanson5@gmail.com>
Co-authored-by: zzak <zzakscott@gmail.com>
All of ActiveStorage database modeltable nameshave been hard coded.
Therefore, ActiveRecord::Base.(prefix|suffix) were not taken into
consideration. To fix this we remove the hard coded lines. But then we
need to also override an internal method for specifying the prefix
because of a mystical ActiveRecord/ActiveStorage sync issue
(Suffix does not appear to have the issue)
Some tests were refactored to remove hard coded table name references,
making ActiveStorage test suite compatible with ActiveRecord config.
Follow-up to #48290.
The `:is(button, input)[type='submit']` selector does not match `button`
elements that omit the `type` attribute in favor relying on its default
value (which is `"submit"`).
Co-authored-by: Javan Makhmali <javan@javan.us>
When a blob is a representable of kind `previewable`, the preview
image that's being proxied is always the original preview image,
discarding completely the `variation_key` param passed in the request.
This commit fixes this by editing `Preview` and `VariantWithRecord` to
have full synchronized API with `Variant`. this will then allow the
ProxyController to not call `representable#image` but `representable`
instead.
As all 3 classes are now 100% interchangeable, we can deprecate the use
of `Representable#image`. Users of this class won't need to call this
method as it's become obsolete. and in case of `Preview#image`
erroneous.
`ActiveStorage::Variant`, the class used to handle untracked variants,
is lacking some methods to make it compliant with
`ActiveStorage::Representations::ProxyController#send_blob_stream`.
This commit fixes the proxying of untracked variant by adding the
missing methods.
Preprocessing "unpresentable" blobs (neither variabe, nor previewable)
will result in a `ActiveStorage::UnrepresentableError`, which will retry
following `ActiveJob::Base` default retry logic.
This commit discards any blob that's not representable to cleanup the
job adapter queue.
if an empty hash is passed to a preview call (`blob.preview({})`)
We go through the original preview instead of regenerating a variation
based on the original preview image which would result in a performance
penalty
This change is necessary to address a potential issue that could arise when a button or an input of type submit contains child elements, such as spans, icons, or other HTML elements.
Currently, ActiveStorage's `didClick` event listener checks the target of the click event to determine if a submit button was clicked. The target property of the event refers to the specific HTML element that was clicked.
In cases where a submit button contains child elements, and one of these child elements is the element that actually gets clicked, the target would refer to this child element, not the button itself.
Since the `didClick` function checks if the target is a button or an input of type submit, this check would fail, and the button wouldn't be stored in `submitButtonsByForm`.
As a result, if the form is then submitted after a direct upload, the first submit button in the form could be incorrectly used to submit the form, even if a different button was originally clicked. This could cause unexpected behavior, as different submit buttons might be intended to trigger different actions on form submission.
By using the `event.currentTarget` instead, we'll get back the button or an input of type submit. This way we ensure that the correct button is stored in `submitButtonsByForm`, even if the click event was triggered by a child element of the button. This addresses the issue and ensures that the correct button is used to submit the form after a direct upload.
https://developer.mozilla.org/en-US/docs/Web/API/Event/currentTarget
Prior to this commit, `ActiveStorage::Preview#processed` would only
process the preview image, not the specified variant of the preview
image. For example, `thumb = attached_pdf.preview(:thumb).processed`
would only generate the full-sized preview image, not the `:thumb`
variant of it, until e.g. `thumb.url` was called.
This commit updates `ActiveStorage::Preview#processed` to generate both
the full-sized preview image and the requested variant.
Co-authored-by: chaadow <chedli@hoggo.com>
`ActiveStorage::Preview#url` delegates to the preview image's variant,
which in turn delegates to the variant's blob. Thus when the variant
has already been processed and strict loading is enabled, the
association chain of `preview_image_attachment` => `blob` =>
`variant_records` => `image_attachment` => `blob` must be fully
pre-loaded; otherwise, `ActiveStorage::Preview#url` will raise an
`ActiveRecord::StrictLoadingViolationError`.
This ensures `ActiveRecord::Base.strict_loading_by_default` and
`ActiveStorage.track_variants` are reset to their original values even
when an error (e.g. an assertion failure) is raised inside
`with_strict_loading_by_default` and `without_variant_tracking` blocks.
The transform_job crahes if you want to preprocess a previewable files.
This commit fixes that by using the blob's `representation` method to
process variants or previews.
Co-authored-by: Jonathan Hefner <jonathan@hefner.pro>
This adds `linguist-generated` and `linguist-vendored` attributes where
appropriate to suppress the files in diffs and exclude the files from
the project's language stats on GitHub.
See https://github.com/github/linguist for more information.
Prior to this commit, if `app/javascript/activestorage/index.js`
contained a syntax error, `JavascriptPackageTest` would still pass
because `system "yarn build"` would simply return `false` and the
compiled output would not change. This commit adds `exception: true` to
the `system` call so that an error will be raised if `yarn build` fails.
Also, since 6c96e1cd7bf3b7089c9b59b2ebeb35bfa6fb3f88, Active Storage
compiles an additional `app/assets/javascripts/activestorage.esm.js`
file. This commit adds an assertion for that file as well.
Remove the option `config.public_file_server.enabled` from the generators for all environments, as the value is the same in all environments.
Co-authored-by: Jonathan Hefner <jonathan@hefner.pro>
`service` kwarg in `has_one_attached` and `has_many_attached` methods accepts
only symbols as values. It allows to define a `service` at a class-level context. But in
one of our requirements, we wanted to upload files based on user's region due to
some regulations.
So in order to allow defining a `service` at instance-level context,
this PR makes the changes to accept `service` as a Proc as well.
Co-authored-by: Jonathan Hefner <jonathan@hefner.pro>
FFmpeg 6.0 now reports the duration of `video_without_video_stream.mp4`
as 1.000000 instead of 1.022000. This discrepancy was [reported][]
to the FFmpeg mailing list, and the [reply][] indicated that the change
is intentional.
For this test, the exact duration isn't significant. We merely want to
assert that the metadata includes the duration reported by FFmpeg.
Therefore, this commit changes the assertion to accomodate the duration
reported by FFmpeg 6.0 as well as previous versions.
Fixes#49650.
[reported]: https://ffmpeg.org/pipermail/ffmpeg-user/2023-October/057067.html
[reply]: http://ffmpeg.org/pipermail/ffmpeg-user/2023-October/057083.html
Co-authored-by: Yasuo Honda <yasuo.honda@gmail.com>
Follow-up to #47137.
Since `config.public_file_server.enabled` is true by default, this
commit changes the `config/environments/production.rb` template to
present the setting as an opt-out.
For better or worse, the Rails guide settled on double quotes
and a large part of the community also use rubocop which enforce
them by default.
So we might as well try to follow that style when providing code
snippets in the documentation or error messages.
Fix: https://github.com/rails/rails/issues/49822
I certainly didn't get them all, but consistency should be significantly
improved.
ActiveStorage::Attachment records are not directly maintained by
ActiveStorage and it may not be feasible or desired to update the record
when its attachment is saved.
Right now we are using both to test the Rails applications we generate
and to test Rails itself. Let's keep CI for the app and BUILDKITE to
the framework.
It's possible since Rails 6 (3ea2857943dc294d7809930b4cc5b318b9c39577) to let the framework create Event objects, but the guides and docs weren't updated to lead with this example.
Manually instantiating an Event doesn't record CPU time and allocations, I've seen it more than once that people copy-pasting the example code get confused about these stats returning 0. The tests here show that - just like the apps I've worked on - the old pattern keeps getting copy-pasted.
This is a follow-up to https://github.com/rails/rails/pull/45606
We were storing the file metadata in Blob and Attachment but we were not
actually uploading the files (into the file system for instance for disk
storage).
It was failing silently so I made it explicit what is accepted and what
is unexpected
### Why was this change necessary?
When creating models in tests, it's easier to pass a File or a Pathname
(from `file_fixture` for instance) to `Model.create` for instance
### How does it address the problem?
When attaching an attachable, we check if it's a File or a Pathname and
handle it appropriately.
There are assertions that expected/actual arguments are passed in the
reversed order by mistake. Enabling the LiteralAsActualArgument rule
prevents this mistake from happening.
The existing tests were auto-corrected by rubocop with a bit of
indentation adjustment.
Co-authored-by: Jonathan Hefner <jonathan@hefner.pro>
These methods were added in b221a4dc43368a1b6f00476f7c5f6047c5c7eea4
But they don't seem to be used by Rails internally or have any tests, so
I assume they were added by accident?
As they both seem to be marked as :nodoc: on ActiveStorage::Blob, we can
remove them without a deprecation warning.
If we decide to keep these methods, they should be added to
ActiveStorage::VariantWithRecord as well. No one complaining about there
methods missing on ActiveStorage::VariantWithRecord is another reason
these methods aren't used.
Both `Nokogiri` and `Minitest` have merged the PRs mentioned to
integrate support for Ruby's Pattern matching
(https://github.com/sparklemotion/nokogiri/pull/2523 and
https://github.com/minitest/minitest/pull/936, respectively).
This commit adds coverage for those new assertions, and incorporates
examples into the documentation for the `response.parsed_body` method.
In order to incorporate pattern-matching support for JSON responses,
this commit changes the response parser to call `JSON.parse` with
[object_class: ActiveSupport::HashWithIndifferentAccess][object_class],
since String instances for `Hash` keys are incompatible with Ruby's
syntactically pattern matching.
For example:
```ruby
irb(main):001:0> json = {"key" => "value"}
=> {"key"=>"value"}
irb(main):002:0> json in {key: /value/}
=> false
irb(main):001:0> json = {"key" => "value"}
=> {"key"=>"value"}
irb(main):002:0> json in {"key" => /value/}
.../3.2.0/lib/ruby/gems/3.2.0/gems/irb-1.7.4/lib/irb/workspace.rb:113:in `eval': (irb):2: syntax error, unexpected terminator, expecting literal content or tSTRING_DBEG or tSTRING_DVAR or tLABEL_END (SyntaxError)
json in {"key" => /value/}
^
.../ruby/3.2.0/lib/ruby/gems/3.2.0/gems/irb-1.7.4/exe/irb:9:in `<top (required)>'
.../ruby/3.2.0/bin/irb:25:in `load'
.../ruby/3.2.0/bin/irb:25:in `<main>'
```
When the Hash maps String keys to Symbol keys, it's able to be pattern
matched:
```ruby
irb(main):005:0> json = {"key" => "value"}.with_indifferent_access
=> {"key"=>"value"}
irb(main):006:0> json in {key: /value/}
=> true
```
[object_class]: https://docs.ruby-lang.org/en/3.2/JSON.html#module-JSON-label-Parsing+Options
Pluses cannot be used to create code blocks when the content includes a
space.
Found using a regular expression:
```bash
$ rg '#\s[^+]*\+[^+]*\s[^+]*\S\+'
```
Before this commit, when a file was uploaded to a mirror service,
the file upload to each service (primary and mirrors) was happening
synchronously:
```rb
def upload(key, io, checksum: nil, **options)
each_service.collect do |service|
io.rewind
service.upload key, io, checksum: checksum, **options
end
end
```
In this commit, we change this behavior to only upload the file to the
primary service synchronously and then enqueue a job to upload the
file to the mirrors asynchronously.
ActiveStorage variants are processed on the fly when they are needed but
sometimes we're sure that they are accessed and want to processed them
upfront.
`preprocessed` option is added when declaring variants.
```
class User < ApplicationRecord
has_one_attached :avatar do |attachable|
attachable.variant :thumb, resize_to_limit: [100, 100], preprocessed: true
end
end
```
`has_one_attached` and `has_many_attached` generate several scopes and
relations:
* `with_attached_*`
* `*_attachment`
* `*_attachments`
* `*_blob`
* `*_blobs`
But these are all undocumented.
We can document these methods similar to ee58c8e6be using the
`:method:` directive.
Fixes an explosion of active storage queries when accessing variants for multiple records.
The implementation is now consistent with that of `has_many_attached`.
Attachments can already be removed by updating the attachment to be nil such as:
```ruby
User.find(params[:id]).update!(avatar: nil)
```
However, a form cannot post a nil param, it can only post an empty string. But, posting an
empty string would result in an `ActiveSupport::MessageVerifier::InvalidSignature: mismatched digest`
error being raised, because it's being treated as a signed blob id.
Now, nil and an empty string are treated as a delete, which allows attachments to be removed via:
```ruby
User.find(params[:id]).update!(params.require(:user).permit(:avatar))
```
This clarifies that the boolean interpretation (1) is due to YAML rather
than I18n, (2) is case insensitive, and (3) affects both keys and
values.
Co-authored-by: Jonathan Hefner <jonathan@hefner.pro>
Background
----------
During integration tests, it is desirable for the application to respond
as closely as possible to the way it would in production. This improves
confidence that the application behavior acts as it should.
In Rails tests, one major mismatch between the test and production
environments is that exceptions raised during an HTTP request (e.g.
`ActiveRecord::RecordNotFound`) are re-raised within the test rather
than rescued and then converted to a 404 response.
Setting `config.action_dispatch.show_exceptions` to `true` will make the
test environment act like production, however, when an unexpected
internal server error occurs, the test will be left with a opaque 500
response rather than presenting a useful stack trace. This makes
debugging more difficult.
This leaves the developer with choosing between higher quality
integration tests or an improved debugging experience on a failure.
I propose that we can achieve both.
Solution
--------
Change the configuration option `config.action_dispatch.show_exceptions`
from a boolean to one of 3 values: `:all`, `:rescuable`, `:none`. The
values `:all` and `:none` behaves the same as the previous `true` and
`false` respectively. What was previously `true` (now `:all`) continues
to be the default for non-test environments.
The new `:rescuable` value is the new default for the test environment.
It will show exceptions in the response only for rescuable exceptions as
defined by `ActionDispatch::ExceptionWrapper.rescue_responses`. In the
event of an unexpected internal server error, the exception that caused
the error will still be raised within the test so as to provide a useful
stack trace and a good debugging experience.
We are using two libraries to do the same job. This commit removes the usage of mini_mime in favour of Marcel instead.
Changes are as follows:
- Replace MiniMime lookup by extension with Marcel Mimetype for lookup with extension
- Replaces usage of MiniMime lookup by content type to fetch extension with usage of Marcel Magic lookup. Marcel has multiple extentions being returned, we pick the first one. MiniMime always returns just one
- Removes specs which we specifically checking failing identification issue of MiniMine on jpeg images
- Removes mini_mime from gemspec
Currently when opening the main framework pages there is no introduction
to the framework. Instead we only see a whole lot of modules and the
`gem_version` and `version` methods.
By including the READMEs using the `:include:` directive each frameworks
has a nice introduction.
For markdown READMEs we need to add the :markup: directive.
[ci-skip]
Co-authored-by: zzak <zzakscott@gmail.com>
* Remove Copyright years
* Basecamp is now 37signals... again
Co-authored-by: David Heinemeier Hansson <dhh@hey.com>
---------
Co-authored-by: David Heinemeier Hansson <dhh@hey.com>