Reputation: 180
I have an attachment, that is passed to the frontend through a serializer as follows.
module NameOfSerializer
class Base < ActiveModel::Serializer
attributes :id,
...
...
...
:attachment_url
def attachment_url
Rails.application
.routes.url_helpers
.rails_blob_url(object.attachment, host: ENV['HOST_URL'])
end
end
end
On development and staging, it works perfectly. I can copy paste the URL and one can open and view the attachment. But on production, it's showing a page with 404 error.
This is what I found in the AWS Elastic Beanstalk log.
[2019-02-04T03:50:38.733073 #16644] INFO -- : [4ca0d491-66cc-4594-9db4-75da533d2fbc] Started GET "/rails/active_storage/blobs/insert_signed_id_here/20190131_214818%20copy%202.jpg" at 2019-02-04 03:50:38 +0000
I, [2019-02-04T03:50:38.736005 #16644] INFO -- : [4ca0d491-66cc-4594-9db4-75da533d2fbc] Processing by ActiveStorage::BlobsController#show as JPEG
I, [2019-02-04T03:50:38.736056 #16644] INFO -- : [4ca0d491-66cc-4594-9db4-75da533d2fbc] Parameters: {"signed_id"=>"insert the signed_id here", "filename"=>"20190131_214818 copy 2"}
D, [2019-02-04T03:50:38.737552 #16644] DEBUG -- : [4ca0d491-66cc-4594-9db4-75da533d2fbc] [1m[36mActiveStorage::Blob Load (0.9ms)[0m [1m[34mSELECT "active_storage_blobs".* FROM "active_storage_blobs" WHERE "active_storage_blobs"."id" = $1 LIMIT $2[0m [["id", 16], ["LIMIT", 1]]
I, [2019-02-04T03:50:38.737936 #16644] INFO -- : [4ca0d491-66cc-4594-9db4-75da533d2fbc] Completed 404 Not Found in 2ms (ActiveRecord: 0.9ms)
F, [2019-02-04T03:50:38.740120 #16644] FATAL -- : [4ca0d491-66cc-4594-9db4-75da533d2fbc]
F, [2019-02-04T03:50:38.740163 #16644] FATAL -- : [4ca0d491-66cc-4594-9db4-75da533d2fbc] ActiveRecord::RecordNotFound (Couldn't find ActiveStorage::Blob with 'id'=16):
F, [2019-02-04T03:50:38.740185 #16644] FATAL -- : [4ca0d491-66cc-4594-9db4-75da533d2fbc]
F, [2019-02-04T03:50:38.740215 #16644] FATAL -- : [4ca0d491-66cc-4594-9db4-75da533d2fbc] activerecord (5.2.0) lib/active_record/core.rb:177:in `find'
I was surprised to see that the log says the Blob with id 16
isn't found, but when I ran rails c
on Elastic Beanstalk, I found the blob.
I also tested another way of retrieving the file from S3 in rails console by running attachment.service_url
.
I was able to access the attachment. Didn't run into 404 errors.
Any ideas? I encountered this issue before and for that issue, I changed to using service_url
but I'd like to know what's causing rails_blob_url
to not work on production environment.
Upvotes: 3
Views: 3395
Reputation: 40386
I just ran into this. Here's how I fixed it for my project.
First, I'm using Amazon S3 for production, but also development. That second part is crucial.
In other words, my config/environments/development.rb
had this:
# Store uploaded files on the local file system (see config/storage.yml for options).
# config.active_storage.service = :local
config.active_storage.service = :amazon
However, this by itself is not enough. For some reason, Rails still tries to use local
when generating urls.
The workaround is to remove the local
config. Here's what my storage.yml
looks like afterwards:
# THE FIX: COMMENTED THIS OUT
# local:
# service: Disk
# root: <%= Rails.root.join("storage") %>
# Use rails credentials:edit to set the AWS secrets (as aws:access_key_id|secret_access_key)
amazon:
service: S3
access_key_id: <%= Rails.application.credentials.dig(:aws, :access_key_id) %>
secret_access_key: <%= Rails.application.credentials.dig(:aws, :secret_access_key) %>
region: us-east-2
bucket: xxx
After restarting the server, everything worked pleasantly.
Upvotes: 3