nil is getting saved for an image in carrierwave - ruby-on-rails

A product can have multiple images. But each image should be uploaded one at a time.
Here is the schema for the product
create_table "products", force: :cascade do |t|
t.json "images"
end
Here is the carrierwave mounting
class Product < ActiveRecord::Base
mount_uploader :images, ProductUploader
end
Here is the carrierwave generator
class ProductUploader < CarrierWave::Uploader::Base
# Include RMagick or MiniMagick support:
# include CarrierWave::RMagick
# include CarrierWave::MiniMagick
# Choose what kind of storage to use for this uploader:
storage :file
# storage :fog
# Override the directory where uploaded files will be stored.
# This is a sensible default for uploaders that are meant to be mounted:
def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
# Provide a default URL as a default if there hasn't been a file uploaded:
# def default_url
# # For Rails 3.1+ asset pipeline compatibility:
# # ActionController::Base.helpers.asset_path("fallback/" + [version_name, "default.png"].compact.join('_'))
#
# "/images/fallback/" + [version_name, "default.png"].compact.join('_')
# end
# Process files as they are uploaded:
# process scale: [200, 300]
#
# def scale(width, height)
# # do something
# end
# Create different versions of your uploaded files:
# version :thumb do
# process resize_to_fit: [50, 50]
# end
# Add a white list of extensions which are allowed to be uploaded.
# For images you might use something like this:
# def extension_whitelist
# %w(jpg jpeg gif png)
# end
# Override the filename of the uploaded files:
# Avoid using model.id or version_name here, see uploader/store.rb for details.
# def filename
# "something.jpg" if original_filename
# end
end
Here is the view
<%= simple_form_for #product, method: :post, url: save_image_path do |f| %>
<%= f.file_field :avatar_1 %>
<%= f.submit :submit %>
<% end %>
Here is the controller
class UploadController < ApplicationController
def show
#product = Product.find(1)
end
def create
byebug
#product = Product.find(1)
#product.images = params[:product][:avatar_1]
#product.save
end
end
But the nil is getting updated in the images of product, instead of image. Can someone please help me with this.

Related

Rails : How to create an object of class within a controller which is in another namespace?

I'm using CarrierWave to upload files from the AngularJS client. The uploader generated for the carrierWave is in another namespace while the controller is in another namespace.
So when I'm trying to create an object of uploader inside the controller, I am getting the following error :
uninitialized constant Api::V1::ProductsController::FileUploader
Here is my directory structure :
app
|--controllers
|--api
|--controllers
|--api
|--v1
|--products_controller.rb
|--uploaders
|--file_uploader.rb
The Products Controller
class Api::V1::ProductsController < ApplicationController
respond_to :json
......
def createFromExcel
puts "------------------------------------"
puts params[:file]
puts "------------------------------------"
uploader = FileUploader.new
uploader.store!(params[:file])
end
end
The FileUploader class :
class FileUploader < CarrierWave::Uploader::Base
# Include RMagick or MiniMagick support:
# include CarrierWave::RMagick
# include CarrierWave::MiniMagick
# Choose what kind of storage to use for this uploader:
storage :file
# storage :fog
# Override the directory where uploaded files will be stored.
# This is a sensible default for uploaders that are meant to be mounted:
def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
# Provide a default URL as a default if there hasn't been a file uploaded:
# def default_url(*args)
# # For Rails 3.1+ asset pipeline compatibility:
# # ActionController::Base.helpers.asset_path("fallback/" + [version_name, "default.png"].compact.join('_'))
#
# "/images/fallback/" + [version_name, "default.png"].compact.join('_')
# end
# Process files as they are uploaded:
# process scale: [200, 300]
#
# def scale(width, height)
# # do something
# end
# Create different versions of your uploaded files:
# version :thumb do
# process resize_to_fit: [50, 50]
# end
# Add a white list of extensions which are allowed to be uploaded.
# For images you might use something like this:
def extension_whitelist
%w(xlsx xls)
end
# Override the filename of the uploaded files:
# Avoid using model.id or version_name here, see uploader/store.rb for details.
# def filename
# "something.jpg" if original_filename
# end
end
How can I create an object of FileUploader class within my Controller?
try using uploader = ::FileUploader.new
To refer to a constant from main (the "global namespace") instead of the current module nesting (the "namespace") use ::
class Api::V1::ProductsController < ApplicationController
respond_to :json
# use snake_case not camelCase
def create_from_excel
uploader = ::FileUploader.new
uploader.store!(params[:file])
end
end
See:
Everything you ever wanted to know about constant lookup in Ruby
Autoloading and Reloading Constants

Carrier Wave mini_magick_processing error

I am trying to upload an image in my signup form using carrierwave gem but getting this error:
Avatar translation missing: en.errors.messages.mini_magick_processing_error
This is my form:
<%= form_for #user do |f| %>
<%= f.label :avatar %>
<%= f.file_field :avatar %>
<%= f.submit "SignUp", class: "btn btn-primary button" %>
<% end %>
<%= image_tag #user.avatar.url %>
and this is my AvatarUploader:
class AvatarUploader < CarrierWave::Uploader::Base
# Include RMagick or MiniMagick support:
# include CarrierWave::RMagick
include CarrierWave::MiniMagick
# Choose what kind of storage to use for this uploader:
storage :file
# storage :fog
# Override the directory where uploaded files will be stored.
# This is a sensible default for uploaders that are meant to be mounted:
def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
# Provide a default URL as a default if there hasn't been a file uploaded:
# def default_url
# # For Rails 3.1+ asset pipeline compatibility:
# # ActionController::Base.helpers.asset_path("fallback/" + [version_name, "default.png"].compact.join('_'))
#
# "/images/fallback/" + [version_name, "default.png"].compact.join('_')
# end
# Process files as they are uploaded:
# process scale: [200, 300]
#
def scale(width, height)
# # do something
end
# Create different versions of your uploaded files:
version :thumb do
process resize_to_fit: [50, 50]
end
# Add a white list of extensions which are allowed to be uploaded.
# For images you might use something like this:
def extension_whitelist
%w(jpg jpeg gif png)
end
# Override the filename of the uploaded files:
# Avoid using model.id or version_name here, see uploader/store.rb for details.
# def filename
# "something.jpg" if original_filename
# end
end

Ruby on Rails: Image Uploads Sideways from Mobile

I'm working on a web application that uses CarrierWave and MiniMagick to handle image uploads for account profile pictures. Right now my AvatarUploader class looks like this
class AvatarUploader < CarrierWave::Uploader::Base
# Include RMagick or MiniMagick support:
# include CarrierWave::RMagick
include CarrierWave::MiniMagick
# In the uploader:
def auto_orient
manipulate! do |img|
img = img.auto_orient
end
end
# Choose what kind of storage to use for this uploader:
# storage :file
# storage :fog
# Override the directory where uploaded files will be stored.
# This is a sensible default for uploaders that are meant to be mounted:
def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
# Provide a default URL as a default if there hasn't been a file uploaded:
def default_url
ActionController::Base.helpers.asset_path('default_avatar.png')
end
# Process files as they are uploaded:
# process :scale => [200, 300]
#
# def scale(width, height)
# # do something
# end
# Create different versions of your uploaded files:
version :thumb do
process :auto_orient
process :resize_to_fill => [200, 200]
end
# Add a white list of extensions which are allowed to be uploaded.
# For images you might use something like this:
# def extension_white_list
# %w(jpg jpeg gif png)
# end
# Override the filename of the uploaded files:
# Avoid using model.id or version_name here, see uploader/store.rb for details.
# def filename
# "something.jpg" if original_filename
# end
end
and the field for handling avatar upload in the form looks like this
.row
- if f.object.avatar.present?
.field
= image_tag f.object.avatar.url
= f.input :avatar, label: f.object.avatar.present? ? 'Replace Avatar' : 'Avatar'
This all works great on the desktop version of my site but when a user uploads a profile pic they take from their mobile phone it gets turned sideways 90 degrees and I can't figure out why. I thought adding the auto_orient code from this question would fix the problem but it did not
credit: #lando2319
exif image rotation issue using carrierwave and rmagick to upload to s3
try changing your auto_orient method to this:
def auto_orient
manipulate! do |img|
img.tap(&:auto_orient!) #try with and without the ! here.
end
end
Figured it out.
process :auto_orient
Needs to be called outside the version: thumb do loop
Full code
# encoding: utf-8
class AvatarUploader < CarrierWave::Uploader::Base
# Include RMagick or MiniMagick support:
# include CarrierWave::RMagick
include CarrierWave::MiniMagick
# In the uploader:
def auto_orient
manipulate! do |img|
img.auto_orient
img
end
end
# Choose what kind of storage to use for this uploader:
# storage :file
# storage :fog
# Override the directory where uploaded files will be stored.
# This is a sensible default for uploaders that are meant to be mounted:
def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
# Provide a default URL as a default if there hasn't been a file uploaded:
def default_url
ActionController::Base.helpers.asset_path('default_avatar.png')
end
# Process files as they are uploaded:
# process :scale => [200, 300]
#
# def scale(width, height)
# # do something
# end
process :resize_to_fit => [400, 400]
process :auto_orient
# Create different versions of your uploaded files:
version :thumb do
process :auto_orient
process :resize_to_fit => [200, 200]
end
# Add a white list of extensions which are allowed to be uploaded.
# For images you might use something like this:
# def extension_white_list
# %w(jpg jpeg gif png)
# end
# Override the filename of the uploaded files:
# Avoid using model.id or version_name here, see uploader/store.rb for details.
# def filename
# "something.jpg" if original_filename
# end
end

Wrong Image path Url using CarrierWave gem

Hello i am using carrievwave gem for uploading images for my rails app which works fine but i am unable to access those uploaded file. i am getting wrong path url http://localhost/uploads/gallery/image_name/354340/1.jpg
(Here '354340' is Userid not autoincremented id )
Current path should be like this http://doitfornow:3000/uploads/gallery/image_name/2/1.jpg
Model
class Gallery < ActiveRecord::Base
attr_accessible :image_name, :name, :user_id,:image_name#,:remote_image_name_url
mount_uploader :image_name, ImageUploader
belongs_to :user, :class_name => "User", :foreign_key => "user_id"
end
View
<%#gallery.each do |f| %>
<tr>
<td class="left"><%= f.Gname%></td>
<!-- # u.avatar.url -->
<td class="left"><%= image_tag f.image_name.url , :size => "50x50" %></td>
<td><%= link_to 'Detail',"/articles/detail?id="+f.Gid.to_s %></td>
<td class="left" colspan="5"><label class="input-control checkbox"><%= check_box_tag 'user_ids[]', f.Gid, false %> <span class="helper"></span></label></td>
</tr>
<% end %>
image_uploder.rb
# encoding: utf-8
class ImageUploader < CarrierWave::Uploader::Base
# Include RMagick or MiniMagick support:
# include CarrierWave::RMagick
# include CarrierWave::jekyll-minimagick
# Include the Sprockets helpers for Rails 3.1+ asset pipeline compatibility:
# include Sprockets::Helpers::RailsHelper
# include Sprockets::Helpers::IsolatedHelper
# Choose what kind of storage to use for this uploader:
storage :file
# storage :fog
# Override the directory where uploaded files will be stored.
# This is a sensible default for uploaders that are meant to be mounted:
def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
# Provide a default URL as a default if there hasn't been a file uploaded:
# def default_url
# # For Rails 3.1+ asset pipeline compatibility:
# # asset_path("fallback/" + [version_name, "default.png"].compact.join('_'))
#
# "/images/fallback/" + [version_name, "default.png"].compact.join('_')
# end
# Process files as they are uploaded:
# process :scale => [200, 300]
#
# def scale(width, height)
# # do something
# end
# Create different versions of your uploaded files:
# version :thumb do
# # process :resize_to_limit => [200, 200]
# process :resize_to_fill => [50, 50]
# # process :scale => [50, 50]
# end
# Add a white list of extensions which are allowed to be uploaded.
# For images you might use something like this:
def extension_white_list
%w(jpg jpeg gif png)
end
# Override the filename of the uploaded files:
# Avoid using model.id or version_name here, see uploader/store.rb for details.
# def filename
# "something.jpg" if original_filename
# end
end
I had the same problem. I did it by creating a module for carrierwave, cause I have more uploaders to handle. I override the 'store_dir' method and add 'set_store_dir' method.
So I can store my files where I want. I set the store_dir in the class including the uploader
Hope it helps
module Helper::Carrierwave
def set_store_dir( dir )
#storedir = dir
end
def store_dir
#storedir
end
end

Default URL not loading with Carrierwave in Rails

I'm having issues setting a default image in my carrierwave uploader. It seems to be appending a weird class to the front of the URL but not rendering the image. See my code below.
Helper
# encoding: utf-8
class UserpicUploader < CarrierWave::Uploader::Base
CarrierWave::SanitizedFile.sanitize_regexp = /[^[:word:]\.\-\+]/
# Include RMagick or MiniMagick support:
include CarrierWave::RMagick
# include CarrierWave::MiniMagick
# Include the Sprokets helpers for Rails 3.1+ asset pipeline compatibility:
# include Sprockets::Helpers::RailsHelper
# include Sprockets::Helpers::IsolatedHelper
# Choose what kind of storage to use for this uploader:
storage :file
# storage :fog
# Override the directory where uploaded files will be stored.
# This is a sensible default for uploaders that are meant to be mounted:
def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
# Process files as they are uploaded:
version :normal do
process :resize_to_fill => [162, 163]
end
# Provide a default URL as a default if there hasn't been a file uploaded:
def default_url
# For Rails 3.1+ asset pipeline compatibility:
# asset_path("fallback/" + [normal, "profile_default_pic.png"].compact.join('_'))
"/images/fallback/" + [normal, "profile_default_pic.png"].compact.join('_')
end
#
# def scale(width, height)
# # do something
# end
# Create different versions of your uploaded files:
# version :thumb do
# process :scale => [50, 50]
# end
# Add a white list of extensions which are allowed to be uploaded.
# For images you might use something like this:
def extension_white_list
%w(jpg jpeg gif png)
end
# Override the filename of the uploaded files:
# Avoid using model.id or version_name here, see uploader/store.rb for details.
def filename
if original_filename
#name ||= Digest::MD5.hexdigest(File.dirname(current_path))
"#{#name}.#{file.extension}"
end
end
end
EDIT...
Here is the edited code that worked. I had to put the image in public/fallback instead of Assets/images/fallback.
# encoding: utf-8
class UserpicUploader < CarrierWave::Uploader::Base
CarrierWave::SanitizedFile.sanitize_regexp = /[^[:word:]\.\-\+]/
# Include RMagick or MiniMagick support:
include CarrierWave::RMagick
# include CarrierWave::MiniMagick
# Include the Sprokets helpers for Rails 3.1+ asset pipeline compatibility:
include Sprockets::Helpers::RailsHelper
include Sprockets::Helpers::IsolatedHelper
# Choose what kind of storage to use for this uploader:
storage :file
# storage :fog
# Override the directory where uploaded files will be stored.
# This is a sensible default for uploaders that are meant to be mounted:
def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
# Process files as they are uploaded:
version :normal do
process :resize_to_fill => [162, 163]
end
# Provide a default URL as a default if there hasn't been a file uploaded:
def default_url
# For Rails 3.1+ asset pipeline compatibility:
asset_path("fallback/" + [normal, "profile_default_pic.png"].compact.join('_'))
# "/fallback/" + [normal, "profile_default_pic.png"].compact.join('_')
end
#
# def scale(width, height)
# # do something
# end
# Create different versions of your uploaded files:
# version :thumb do
# process :scale => [50, 50]
# end
# Add a white list of extensions which are allowed to be uploaded.
# For images you might use something like this:
def extension_white_list
%w(jpg jpeg gif png)
end
# Override the filename of the uploaded files:
# Avoid using model.id or version_name here, see uploader/store.rb for details.
def filename
if original_filename
#name ||= Digest::MD5.hexdigest(File.dirname(current_path))
"#{#name}.#{file.extension}"
end
end
end
Ok I got it working this is what I was missing...
The default folder had to be in the public/ folder not in assets/images
I had to add the following lines to the uploader class:
include Sprockets::Helpers::RailsHelper
include Sprockets::Helpers::IsolatedHelper
I had to change the default_url to the following:
asset_path("fallback/" + [normal, "profile_default_pic.png"].compact.join('_'))
In Rails 4.1.* you can just specify the filename in the default_url method
def default_url
"default.png"
end
In this case the default.png should be in /app/assets/images folder
edit the uploader class :
def default_url
"/images/fallback/" + [version_name,"default.png"].compact.join('_')
end
and then copy the default picture in /images/fallback/default.png

Resources