carrierwaveuploader / carrierwave-aws

AWS-SDK storage adapter for CarrierWave
MIT License
409 stars 107 forks source link

Strange routing behavior when submitting forms with File upload/File field in Production #142

Closed Rubioli closed 5 years ago

Rubioli commented 5 years ago

In my application I'm using carrierwave for image upload.

My CampaignsController is a usual create action

def create
  @campaign = Campaign.new(campaign_params)

  respond_to do |format|
    if @campaign.save
      format.html { redirect_to @campaign, notice: 'Campaign was successfully created.' }
      format.json { render :show, status: :created, location: @campaign }
    else
      format.html { render :new }
      format.json { render json: @campaign.errors, status: :unprocessable_entity }
    end
  end
end

Everything works fine in development, but in production after submit/save things go wrong.

By that I mean: In development when form is submitted, after save it goes to localhost:3000/campaigns/38 and my form is: action="campaigns/38".

BUT

In production when form is submitted, after save, instead of going to example.com/campaigns/38, it goes to example.com/campaigns/campaigns/38 and my form changes to: action="campaigns/campaigns/38".

As you can see that extra campaigns is in the URL and I'm not sure why. It seems rails changed my root from example.com to example.com/campaigns

This is my routes.rb:

Rails.application.routes.draw do
  resources :campaigns 

  # match '*any' => 'application#options', :via => [:options]
end

This is my ImageUploader:

class ImageUploader < CarrierWave::Uploader::Base
  include CarrierWave::MiniMagick

  storage :aws

  def store_dir
      "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
  end

  version :large do
    resize_to_limit(600, 600)
  end

My carrierwave.rb:

CarrierWave.configure do |config|
  config.storage    = :aws
  config.aws_bucket = 'my-bucket'
  config.aws_authenticated_url_expiration = 60 * 60 * 24 * 7

  # Set custom options such as cache control to leverage browser caching
  config.aws_attributes = {
      expires: 1.week.from_now.httpdate,
      cache_control: 'max-age=604800'
  }

  config.aws_credentials = {
      access_key_id:     'myKeyId',
      secret_access_key: 'superSecret',
      region:            'us-west-1', # Required
  }
end

My Campaign Model:

class Campaign < ApplicationRecord
  mount_uploader :image, ImageUploader

This is my application version:

ruby "2.3.1"
gem 'rails', '~> 5.2.2'
carrierwave (~> 1.3, >= 1.3.1)
carrierwave-aws (1.3.0)

I've been testing with different things to see what exactly is the issue. I tested with simple_form_for, form_for and even removed parts of the form.

Everything works as long as = f.file_field :image is not there. when I remove = f.file_field :image from my form everything works fine in all ENVs, but when I add it back, its than Production has this strange behavior.

I also change redirect_to to render: format.html { render :show} and when doing this, I dont get route error but ALL links in that pages (such as navigation links), changes to example.com/campaigns/dashboard, example.com/campaigns/users and when I populate root_path in my view, it said: example.com/campagins.

When I get route error, in error page, I can some routes that I have never seen, been added to error page:

skjermbilde 2019-02-14 13 39 37

Any help is appreciated and thanks in advance!

sorentwo commented 5 years ago

This seems like a host/asset_host configuration problem in production. Regardless, this definitely isn't a carrierwave-aws issue.

Also, from your routes it looks like you are using ActiveStorage as well, which you would use instead of CarrierWave. If you're starting a new application and want to do it The Rails Way, you may want to use ActiveStorage instead.

Rubioli commented 5 years ago

@sorentwo Thanks a lot for your reply.

This might be out of line and I would appreciate if you could give me some pointers. Do you mean that since I use carrierwave now, I wouldn't need to use ActiveStorage if so would you please let me know how I can "turn it off"?

If you don't have the time to give me some pointers, I of course understand and already thank you for taking carrierwave-aws from the problem-list

sorentwo commented 5 years ago

I'm suggesting that you use ActiveStorage if you have straight forward asset needs, since it is bundled with Rails. If you'd prefer to use CarrierWave then you would have to avoid loading rails globally and load individual packages instead.

Rubioli commented 5 years ago

Thanks a lot @sorentwo. appreciate you taking your time 💯