Search code examples
ruby-on-railsrubyherokurails-activestorage

Localhost works, but Heroku throws 500 when uploading photo with active_storage and Rails 5.2


I'm trying to do a basic photo upload with ActiveStorage and Rails 5.2. It works perfectly on localhost but runs into a 500 error when I try to create a new object in Heroku. Unfortunately, the Heroku logs aren't being helpful at all:

2018-08-11T20:06:44.886851+00:00 app[web.1]: http://mab-staging.herokuapp.com/products/new -> /products
2018-08-11T20:06:44.886308+00:00 heroku[router]: at=info method=POST path="/products" host=mab-staging.herokuapp.com request_id=6557c78a-fbc1-4059-9904-c4b1122f8930 fwd="68.225.227.137" dyno=web.1 connect=0ms service=79ms status=302 bytes=1304 protocol=http
2018-08-11T20:06:45.143034+00:00 heroku[router]: at=info method=GET path="/products" host=mab-staging.herokuapp.com request_id=46ba7cc2-953a-4236-806c-44248a9625fe fwd="68.225.227.137" dyno=web.1 connect=1ms service=153ms status=500 bytes=1262 protocol=http
2018-08-11T20:06:45.143727+00:00 app[web.1]: 10.7.204.125 - - [11/Aug/2018:20:06:44 UTC] "GET /products HTTP/1.1" 500 939
2018-08-11T20:06:45.143819+00:00 app[web.1]: http://mab-staging.herokuapp.com/products/new -> /products
2018-08-11T20:06:45.667492+00:00 heroku[router]: at=info method=GET path="/favicon.ico" host=mab-staging.herokuapp.com request_id=752f97ad-deea-41ed-af16-5a9c67f0329c fwd="68.225.227.137" dyno=web.1 connect=0ms service=20ms status=304 bytes=133 protocol=http
2018-08-11T20:06:45.668380+00:00 app[web.1]: 10.7.204.125 - - [11/Aug/2018:20:06:45 UTC] "GET /favicon.ico HTTP/1.1" 304 0
2018-08-11T20:06:45.668476+00:00 app[web.1]: http://mab-staging.herokuapp.com/products -> /favicon.ico

I have all the steps included in this Heroku documentation/tutorial.

I have installed ActiveStorage and ran rake db:migrate locally and on Heroku.

My products#create and products#update methods are like this:

 def create
    @product = Product.new(product_params)
    @product.product_image.attach(params[:product][:product_image])
    @product.save
    flash[:notice] = "Your product has been created!"
    redirect_to products_path
  end

  def update
    @product = Product.find(params[:id])
    @product.product_image.attach(params[:product][:product_image])
    if @product.update_attributes(product_params)
      redirect_to products_path
      flash[:notice] = "That product has been updated."
    else
      render :action => :edit
      flash[:alert] = "Something went terribly wrong there..."
    end
  end

My form field is simple:

    <div class="form-group col-xs-12">
      <%= f.file_field :product_image %>
    </div> <!-- form group -->

I have the following in my Gemfile and have run bundle install and bundle update:

gem 'activestorage'
gem 'aws-sdk', '~> 3' #AWS
gem 'mini_magick', '~> 4.8'

I have this in production.rb and staging.rb:

  # Store files on Amazon S3.
  config.active_storage.service = :amazon

And this in storage.yml:

local:
  service: Disk
  root: <%= Rails.root.join("storage") %>

test:
  service: Disk
  root: <%= Rails.root.join("tmp/storage") %>

amazon:
  service: S3
  access_key_id: <%= ENV['AWS_ACCESS_KEY_ID'] %>
  secret_access_key: <%= ENV['AWS_SECRET_ACCESS_KEY'] %>
  region: <%= ENV['AWS_REGION'] %>
  bucket: <%= ENV['S3_BUCKET_NAME'] %>

I did this, even though I don't completely understand what it does:

 heroku buildpacks:add -i 1 https://github.com/heroku/heroku-buildpack-activestorage-preview

I have this in my product.rb model:

has_one_attached :product_image

Can anyone see any reason this is working locally but not on Heroku? I'm tapped...

ADDITIONAL INFORMATION

After some heroku logs assistance, I have more detailed logs:

2018-08-11T21:16:51.614163+00:00 app[web.1]: Completed 500 Internal Server Error in 139ms (ActiveRecord: 21.6ms)
2018-08-11T21:16:51.617425+00:00 app[web.1]: 
2018-08-11T21:16:51.617550+00:00 app[web.1]: ActionView::Template::Error (to_model delegated to attachment, but attachment is nil):
2018-08-11T21:16:51.617809+00:00 app[web.1]: 3:   <div class="row">
2018-08-11T21:16:51.617812+00:00 app[web.1]: 4:     <div class="col-sm-3 text-center">
2018-08-11T21:16:51.617814+00:00 app[web.1]: 5:       <% if product.product_image %>
2018-08-11T21:16:51.617819+00:00 app[web.1]: 6:         <%= image_tag url_for(product.product_image), alt: product.name, style: "max-width: 100%; max-height: 200px" %>
2018-08-11T21:16:51.617822+00:00 app[web.1]: 7:       <% end %>
2018-08-11T21:16:51.617823+00:00 app[web.1]: 8:     </div>
2018-08-11T21:16:51.617825+00:00 app[web.1]: 9:
2018-08-11T21:16:51.617878+00:00 app[web.1]: 
2018-08-11T21:16:51.617936+00:00 app[web.1]: app/views/products/_product_row.html.erb:6:in `_app_views_products__product_row_html_erb__1069905907297071252_46241260'
2018-08-11T21:16:51.617938+00:00 app[web.1]: app/views/products/index.html.erb:21:in `block in _app_views_products_index_html_erb___2131941533006009981_47014040'
2018-08-11T21:16:51.617940+00:00 app[web.1]: app/views/products/index.html.erb:20:in `_app_views_products_index_html_erb___2131941533006009981_47014040'
2018-08-11T21:16:51.630658+00:00 app[web.1]: 10.148.82.74 - - [11/Aug/2018:21:16:51 UTC] "GET /products HTTP/1.1" 500 939
2018-08-11T21:16:51.630751+00:00 app[web.1]: https://www.manlyartofbbq.com/products/new -> /products

Unfortunately, it looks like this is saying the attachment is nil, even though it shouldn't be, so for some reason the product_image isn't getting uploaded properly...


Solution

  • This issue never really got resolved, but I sidestepped it by deleting my database records for the table in question and re-uploading them. It appears to have been a conversion from Paperclip-uploaded photos to ActiveStorage-uploaded photos issue.