1
votes

I'm adding a photo uploader and would like to add a default image if a user photo isn't uploaded ? Would like to know what's wrong with my 'if' statement.

I'm just getting out of a coding bootcamp so excuse the newbie code. Apologize in advance for that. The image shows in my navbar if I upload it but if I don't upload it nothing will show in my navbar.

This is my user.rb file

class User < ApplicationRecord
  def set_photo
    if self.photo.nil?
      @photos = ['monsters/1', 'monsters/2', 'monsters/3', 'monsters/4', 'monsters/5', 'monsters/6', 'monsters/7', 'monsters/8']
      self.photo = @photos.sample
      self.save!
    end
  end

This is my navbar

<% if user_signed_in? %>
  <li class="nav-item dropdown">
    <%= cl_image_tag current_user.photo, class: "avatar dropdown-toggle", id: "navbarDropdown", data: { toggle: "dropdown" }, 'aria-haspopup': true, 'aria-expanded': false %>

This is my Users Controller

class UsersController < ApplicationController
  def new
  end

  def show
  end

  def dashboard
    @group = Group.new
    @user_group = UserGroup.new
    @user_groups = current_user.user_groups
    @groups = current_user.groups
    @user = current_user
  end

  def update
    current_user.available_balance += params[:user][:deposit].to_f unless params[:user][:deposit].nil?
    current_user.available_balance -= params[:user][:withdrawal].to_f unless params[:user][:withdrawal].nil?
    current_user.save!
    redirect_to dashboard_path
  end

  private

  def user_params
    params.require(:user).permit(:first_name, :last_name, :photo)
  end
end

This is my PhotoUploader

class PhotoUploader < CarrierWave::Uploader::Base
  include Cloudinary::CarrierWave
end

I don't receive any error messages but the image uploads fine and the avatar goes into the navbar but if I dont upload an image nothing appears at all and it won't grab a default "monster" pic.

1

1 Answers

0
votes

According to official carrierwave documentation you should provide default_url, like this:

class MyUploader < CarrierWave::Uploader::Base
  def default_url(*args)
    "/images/fallback/" + [version_name, "default.png"].compact.join('_')
  end
end

For your case it may looks so:

class PhotoUploader < CarrierWave::Uploader::Base
  def default_url(*args)
    ActionController::Base.helpers.asset_path("fallback/" + [version_name, "default.png"].compact.join('_'))
  end
end

After that you should create fallback folder under assets/images and put default.png file into it. Don't forget to restart you application.

Also, you should mount PhotoUploader at your User model:

class User < ApplicationRecord
  mount_uploader :photo, PhotoUploader
  ...
end

UPDATE

I never used cloudinary gem before, but after some search I found this blog post

From #default_public_id you should return the public id of an already uploaded image, e.g. ‘avatar’.

The #default_url method lets you specify a URL to use, skipping Cloudinary completely, so you could use an asset in your project.

The final point to note is that when you use the image in the view you must call #url on your version, else the defaults do not get used.

And example:

class Client::HeadshotUploader < CarrierWave::Uploader::Base
 include Cloudinary::CarrierWave

 version :circle do
   cloudinary_transformation format: :png, transformation: [
     {effect: :improve},
     {width: 300, height: 300, crop: :thumb, gravity: :face, radius: :max}
   ]
 end

 def default_public_id
   'headshot'
 end
end

and then in your view

<%= cl_image_tag client.headshot.circle.url %>