I've been trying to implement direct upload with AWS and CarrierWave direct. I'm following the documentation.
I have a model: AppNotice. It has a column called image
.
However, it seems like even though my model has the code mount_uploader :image, AppNoticesImageUploader
, it does not have the key attribute.
Here's my uploader app_notices_image_uploader.rb
:
class AppNoticesImageUploader < CarrierWave::Uploader::Base
include CarrierWaveDirect::Uploader
process optimize: [{ quality: 50, level: 7 }] # Função executada antes do upload
process :pngquant, if: :is_png?
def store_dir
'uploads/app_notices'
end
end
And my carriewrwave config file:
# frozen_string_literal: true
require 'carrierwave/storage/fog'
CarrierWave.configure do |config|
# config.asset_host = ENV['ASSET_HOST_UPLOAD']
config.storage = :fog
config.fog_provider = 'fog/aws'
config.fog_directory = ENV['FOG_DIRECTORY'] # S3 bucket
config.fog_attributes = { 'Cache-Control' => 'max-age=315576000' }
config.fog_credentials = {
region: ENV['FOG_REGION'],
provider: ENV['FOG_PROVIDER'],
aws_access_key_id: ENV['AWS_ACCESS_KEY_ID'],
aws_secret_access_key: ENV['AWS_SECRET_ACCESS_KEY']
}
config.cache_dir = "#{Rails.root}/tmp/uploads"
end
My upload form is pretty simple and it is on the same page of my "normal" form for app notices:
<%= direct_upload_form_for @uploader do |fi| %>
<%= fi.file_field :image, onchange: 'validateSize(this, 5)' %>
<%= fi.submit %>
<% end %>
the validateSize
function just validates if the image has less than 5MB.
The app notices form is under it, they don't have anything to do with each other.
Here's my new
action on app_notices_controller:
def new
@app_notice = AppNotice.new
if params[:key].nil?
@uploader = @app_notice.image
@uploader.success_action_redirect = new_brand_app_notice_url(@brand)
else
## these are the examples i've tried and none of them worked
# @uploader.update_attribute(:image_key, params[:key]) << undefined method `update_attribute' for #<AppNoticesImageUploader:0x00005648f4ff6778>
# @uploader.key = params[:key] << this one does not change anything
# @app_notice.image.key = params[:key] << this one does not change anything
# @app_notice.update_attribute(:key, params[:key]) undefined method `key=' for #<AppNotice:0x00007f49fd0018f8>
# @app_notice.assign_attributes(:image_key, params[:key]) << undefined method `reject' for :image_key:Symbol
@uploader = @app_notice.image
# @app_notice.update_attribute(:image_key, params[:key]) # null value in column "description" violates not-null constraint
# DETAIL: Failing row contains (573, a92a2c73-0aa5-4695-8946-d56b65553d0b/yamper.png, null, f, null, 2021-12-15 12:53:43.965459, 2021-12-15 12:53:43.965459, null, null, null, null).
end
end
It is said that CarrierWaveDIrect adds the key attribute automatically and I can't get to it. So there should be and attribute key
in the AppNotice model, but there isn't.
My model:
class AppNotice < ActiveRecord::Base
mount_uploader :image, AppNoticesImageUploader
validate :validate_image_size, if: 'image.present?'
private
def validate_image_size
image = MiniMagick::Image.open(image_url)
if image[:height] > 750
errors.add :image, 'A altura da imagem deve ser no máximo 750px.'
end
if image[:width] > 750
errors.add :image, 'A largura da imagem deve ser no máximo 750px.'
end
rescue StandardError
errors.add(:base, 'Erro ao salvar a imagem')
end
end
The only question I found about this was No update_attribute method on carrier wave direct and none of the solutions worked for me.