I could have split this into several commits:
* DRY direct linking to images.
* Check S3 config before direct linking.
* Just check if service is public instead of relying on name.
Developers may copy a staging or production database or experiment with
S3 storage. But when the S3 config is missing then calling `service`
raises an ArgumentError due to a missing name.
Now we only try to call `service` if the S3 config is present.
We configured Paperclip to convert images to JPG in some cases but I
omitted that here because we don't need it. If an image is better
represented as PNG or another format then the user should be able to
choose that.
Some specs were also testing the generated URL but the Active Storage
URL doesn't contain a style name anymore and it's not helpful to test
the URL.
While we migrate from Paperclip to Active Storage, we need to use both
at the same time to avoid any downtime or lost images.
Once the migration is complete, we want to use the same name for
attachment as before. Using Paperclip and Active Storage at the same
time creates a name conflict on a couple of methods.
I'm using alias_method as a temporary solution to access Active Storage
methods. We will remove that after the migration. I declare Paperclip
afterwards so that we have those methods declarations for backwards
compatibility now.
The S3 class is calling URI.encode which is removed in Ruby 3. By
providing a URI module within the S3 class makes the S3 code call that
module instead.