Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fix ActiveStorage::Blob inverse association:
- This is a fix needed to unblock rails#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: https://github.com/rails/rails/blob/9c3ffab47c3bf59320ba08e9dafdb0275cf91a5a/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 rails#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`.
- Loading branch information