Commit Graph

350 Commits

Author SHA1 Message Date
Edouard CHIN 82d4ad5da3 Fix ActiveStorage::Blob inverse association:
- This is a fix needed to unblock
  https://github.com/rails/rails/pull/50284,
  because Active Storage relies on a Active Record bug.

  The problem is best understood with a small snippet:

  ```
    blob = ActiveStorage::Blob.new

    ActiveStorage::Attachment.new(blob: blob)
    ActiveStorage::Attachment.new(blob: blob)

    # Currently:
    p blob.attachments #=> #<ActiveRecord::Associations::CollectionProxy []>

    # Once the Active Record bug is fixed:
    p blob.attachments #=> #<ActiveRecord::Associations::CollectionProxy [#<ActiveStorage::Attachment id: nil, name: nil, record_type: nil, record_id: nil, blob_id: nil, created_at: nil>, #<ActiveStorage::Attachment id: nil, name: nil, record_type: nil, record_id: nil, blob_id: nil, created_at: nil>]>

    # Trying to save the blob would result in trying to create 2 attachments which
    # fails because of unique constrainsts.
  ```

  ### Code path

  The real code path that does what the snippet above does is located here:

  9c3ffab47c/activestorage/lib/active_storage/attached/many.rb (L52)

  It's basically doing this:

  ```
    user.images.attach "photo1.png"
    # Initialize a Blob record and an Attachment

    user.images.attach "photo2.png"
    # Get the Blob from above, create another Attachment
    # Initialize a new Blob record and an new Attachment

    # rinse and repeat every time `attach` is called
  ```

  Basically each time we call `attach`, we grab the previous blobs that were attached
  (and that already have an Attachment record), and

  ### Solution

  - Explicitly set the `inverse_of`, so that it behaves as if #50284 is shipped
  - Don't build a new attachment for blob already having one.

  ### Tests

  I didn't add tests, the test suite is already well covered, adding the `inverse_of`
  without any changes breaks the test suite already. You can try by running
  for instance the `activestorage/test/models/attached/many_test.rb`.
2024-01-19 04:18:15 +01:00
Aaron Patterson f2f50c904e
Fix N+1 on scope with non-image previews 2024-01-16 09:36:43 -08:00
Akshay Birajdar 92138c40cc Use buffered read while generating checksum for blob 2023-12-22 08:43:58 +05:30
chaadow 4ca61ffacb Take AR affixes into account for AStorage models
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.
2023-12-07 00:01:16 +01:00
Jonathan Hefner 701e17b910 Fix submit button selector for `type`-less buttons
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>
2023-11-24 15:36:13 -06:00
Jonathan Hefner 06f0710061 Prevent autolink to method's own class [ci-skip]
Linking to a class from within its own documentation is more confusing
than helpful.
2023-11-23 11:46:16 -06:00
chaadow f5acef7e48 Fix AS:Representations::ProxyController returning the wrong preview
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.
2023-11-21 21:00:35 +01:00
Jonathan Hefner 5d0ab554e3
Merge pull request #50107 from chaadow/fix_proxy_controller_untracked_variants
[ActiveStorage] Fix Non tracked variants not working with `ActiveStorage::Representations::ProxyController`
2023-11-20 14:46:00 -06:00
chaadow cb3fdaf8e4 Fix representation proxy for untracked variants
`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.
2023-11-20 19:57:01 +01:00
Jonathan Hefner 0ad26f7890
Merge pull request #48290 from marckohlbrugge/patch-1
Support nested elements inside <button>
2023-11-20 11:25:41 -06:00
chaadow 2edcda8576 Discard unrepresentable blobs while preprocessing
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.
2023-11-17 22:44:07 +01:00
chaadow eae19656fe Prevent `AS::Preview#processed` to generate an empty variant
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
2023-11-15 21:01:16 +01:00
Marc Köhlbrugge a1504f457c Support nested elements inside <button>
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
2023-11-13 19:33:53 +00:00
Jonathan Hefner a5e1fc97d2 Process preview variant when processing preview
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>
2023-11-13 11:01:40 -06:00
Jonathan Hefner aa47bde556 Fix strict loading for Active Storage previews
`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`.
2023-11-13 10:58:50 -06:00
Nico Wenterodt 435a347a10 Fix #50005 transform_job not accepting previewables
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>
2023-11-11 11:21:00 -06:00
Jonathan Hefner 4dcd6ba8d3 Update .gitattributes for generated JavaScript [ci-skip]
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.
2023-11-05 15:48:08 -06:00
Yogesh Khater 8bf1353cae Allow accepting `service` as a proc
`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>
2023-11-01 21:20:55 -05:00
Myles Boone 13d66b1632 Add config option to not touch records
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.
2023-10-20 14:41:57 -04:00
Jonathan Hefner 6fddf2e452 Autolink ActiveStorage::Attachment [ci-skip]
This also fixes a formatting error caused by embedding `+` in the middle
of a word.
2023-10-07 11:55:35 -05:00
aki 1f9fbbe213
Add `expires_at` option to `ActiveStorage::Blob#signed_id` 2023-09-26 21:08:20 +00:00
Victor Mours 1bdabc1102 Clarify that the default retry strategy uses polynomial backoff and not exponential backoff 2023-09-16 00:51:14 +02:00
Ryuta Kamizono 099f979dc7
Merge pull request #49195 from p8/activestorage/variant-interface
Keep VariantWithRecord API consistent with Variant
2023-09-08 17:52:05 +09:00
Petrik 1e23fff1a1 Remove unused methods on ActiveStorage::Variant
These methods were added in b221a4dc43
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.
2023-09-08 10:05:56 +02:00
Petrik 3e27f43dbc Keep VariantWithRecord API consistent with Variant
Similar to c18bcd5828 adds the
content_type and filename methods to VariantWithRecord.
2023-09-08 08:24:20 +02:00
Rafael Mendonça França c18bcd5828
Keep VariantWithRecord API consistent with Variant
The `process` and `processed?` methods in Variant are private.
2023-08-23 19:16:39 +00:00
Bryan Traywick 1d212dc357 Fix NoMethodError in ActiveStorage::TransformJob for untracked variants. 2023-08-22 13:01:44 -04:00
Hartley McGuire bac6d8c079
Fix code blocks using + instead of <tt>
Pluses cannot be used to create code blocks when the content includes a
space.

Found using a regular expression:

```bash
$ rg '#\s[^+]*\+[^+]*\s[^+]*\S\+'
```
2023-08-10 13:05:05 -04:00
Alexandre Ruban 9d6b68446d
ActiveStorage mirror uploads should be asynchronous
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.
2023-08-04 09:08:50 +02:00
Rafael Mendonça França 379e3b4d79
Remove empty line 2023-08-03 15:41:58 -04:00
Bruno Prieto 8a88ce1943 Disable session in ActiveStorage blobs and representations proxy controller
This allows CDNs such as CloudFlare to cache files delivered by proxy by default

Fix #44136
2023-08-02 06:44:51 +02:00
Shouichi Kamiya b1c544b1d1 Add an option to preprocessed AS variants
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
```
2023-07-03 19:36:14 +09:00
zzak dd89f600f7
🔗 Remove RDoc auto-link from Rails module everywhere 2023-06-23 10:49:30 +09:00
zzak e3c73fd183
Replace all occurrences of '<tt>(\w+::\w+)</tt>' with '+$1+'
E.g.:

* <tt>ActiveRecord::Base</tt> -> +ActiveRecord::Base+

Co-authored-by: Hartley McGuire <skipkayhil@gmail.com>
Co-authored-by: Petrik de Heus <petrik@deheus.net>
2023-05-25 06:52:32 +09:00
Petrik cb14a98a06 Infer method names for :*-method: directives [ci-skip]
The :method: and :singleton-method: directives infer the method name
by looking at the token after the identifier.
So we don't need to specify them.
2023-05-18 20:51:55 +02:00
Petrik 01508cac4d Document assocations and scopes on ActiveStorage::Attachment/Blob [ci-skip]
Scopes and associations aren't picked up by RDoc, but we can use
`:method` and `:singleton-method:` directives to document them.
2023-05-08 13:27:33 +02:00
Petrik 0e7cb8d327 Add missing headers to Active Storage docs [ci-skip] 2023-04-03 12:29:49 +02:00
Rafael Mendonça França 1ed5ef6bb3
Merge pull request #47773 from Roriz/feat/custom-header-direct-upload
Safe for Direct Uploads in js Libraries or Frameworks
2023-03-27 16:37:25 -04:00
Vipul A M 3d414f3986 Remove mini_mime usage in favour of marcel
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
2023-03-27 23:24:43 +05:30
Radamés Roriz a37f1d4f26
fix: add compiled js from activestorage 2023-03-26 17:05:10 -03:00
Radamés Roriz 0042a51740
fix: typo on js method 2023-03-26 15:52:15 -03:00
Radamés Roriz d81124b3bd
feat: add custom headers on direct upload js class 2023-03-26 14:43:22 -03:00
Rafael Mendonça França febd9ab4f6
Merge PR #47150 2023-03-25 16:55:06 +00:00
Rafael Mendonça França 0591de55af
Remove deprecated `ActiveStorage::Current#host` and `ActiveStorage::Current#host=` methods 2023-03-03 00:38:41 +00:00
Rafael Mendonça França 4edaa4120b
Remove deprecated invalid default content types in Active Storage configurations 2023-03-03 00:38:40 +00:00
Shouichi Kamiya 98abeea7b6 Allow destroying active storage variant
Background:

When creating active storage variants, `ActiveStorage::VariantRecord` is
inserted, then a file is uploaded. Because upload can be failed, the
file can be missing even though `ActiveStorage::VariantRecord` exists.

When a file is missing, we need to delete the corresponding
`ActiveStorage::VariantRecord` but there's no API to delete just one
variant e.g., `blob.variant(resize_to_limit: [100, 100]).destroy`.

Co-authored-by: Yuichiro NAKAGAWA <ii.hsif.drows@gmail.com>
Co-authored-by: Ryohei UEDA <ueda@anipos.co.jp>
2023-02-08 18:36:45 +09:00
zzak 12de399ef9 Replace deprecated Rack::File with Rack::Files
Follow up to #47075
2023-01-21 09:34:21 +09:00
Hartley McGuire a07f2ace03
Fix lots of code highlighting issues
The most common is replacing back-ticks with either pluses or tt tags.
There were also a few instances of code blocks not being indented.
2022-11-29 00:51:02 -05:00
Rafael Mendonça França 153777d3eb
Merge pull request #46548 from Earlopain/blob-rewindable
Validate ActiveStorage::Blob io is rewindable
2022-11-23 13:51:29 -05:00
Earlopain 4a4922b7d3
Validate ActiveStorage::Blob io is rewindable
ActiveStorage::Blob.create_and_upload!(io: file_fixture("test.jpg"), filename: "dummy")

The code looks reasonable, but actually results in an infinite loop
before this change. Now an error is propagated to the user instead.
Closes #46507
2022-11-23 19:10:20 +01:00