User's initial as an avatar image
Tags: ruby, rails
Published: 2022-10-28 16:33:09

---
title: User's initial as an avatar image
published: true
description: User's initial as an avatar image
tags: ruby, rails
# cover_image: https://direct_url_to_image.jpg
# Use a ratio of 100:42 for best results.
# published_at: 2022-10-28 15:53 +0000
---
![Image with the letter 'D'](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/27jpnicrgz7wztex78k4.jpg)

Basecamp does something like this but I do not know exactly how they've done it. This is my take on using an image for the user's avatar, uploaded using Active Storage.

My `profile` model is setup with an `has_one_attached`:
```rb
# profile.rb

has_one_attached :avatar
belongs_to :user

```
User model is not important here but it looks like this:
```rb
# user.rb

has_one :profile

```

The logic is that once the user has registered with their name, we generate the image initial then upload it.
```rb

def generate_avatar(user)
  # The first character from the user's name.
  # Basecamp does some extra checks to check for numbers
  # and alphabet from the name. When invalid, they
  # return a question mark: ?
  initial = user.profile.name.first.upcase
  
  # A colour that will not change for the user: red, green, hex value etc
  colour = user.default_colour

  # A HTML markup with background color; inline or in the css file
  html = "<div style='background:#{colour};width:280px;height:280px' class='custom_avatar'><span>#{initial}</span></div>"

  # See rest of post
  kit = IMGKit.new(html, :width => 280, :quality => 50)
  
  # A custom stylesheet
  kit.stylesheets << "#{Rails.root}/app/assets/stylesheets_custom/custom_avatar.css"
  
  # Store image in a temp folder
  file_path = Tempfile.new(["file", '.jpg']).path
  kit.to_file(file_path)
  
  # Upload the image
  user.profile.avatar.attach(io: File.open(file_path), filename: 'avatar.jpg')
end

```

## The setup

`Gemfile.rb`:
```bash
# https://github.com/csquared/IMGKit
gem 'imgkit'
gem 'wkhtmltoimage-binary'
```
Run `bundle install` to install the gems above. I'm using [IMGKit](https://github.com/csquared/IMGKit).

## Custom Stylesheet
I put this in `app/stylesheets_custom/*`
```css

* {
  margin: 0;
  padding: 0;
}
.custom_avatar {
  width: 280px;
  height: 280px;
  padding: 0;
  margin: 0;
  font-size: 8rem;
  font-weight: bold;
  color: white;
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  -webkit-box-align: center;
      -ms-flex-align: center;
          align-items: center;
  -webkit-box-pack: center;
      -ms-flex-pack: center;
          justify-content: center;
}

```
For reusable methods, I create a module and place in: `controllers/concerns/*`:

```rb
# user_avatar_image.rb

module UserAvatarImage
  
  def random_colour
    ["#A9294F", "#ED6663", "#389393", "#D82148", "#8C5425", "#6F38C5"].sample
  end

  def generate_avatar(user)
    # The first character from the user's name
    initial = user.profile.name.first.upcase
    
    # A colour that will not change for the user: red, green, hex value etc
    colour = user.default_colour

    # A HTML markup with background color; inline or in the css file
    html = "<div style='background:#{colour};width:280px;height:280px' class='custom_avatar'><span>#{initial}</span></div>"

    # See rest of post
    kit = IMGKit.new(html, :width => 280, :quality => 50)
    
    # A custom style sheet
    kit.stylesheets << "#{Rails.root}/app/assets/stylesheets_custom/custom_avatar.css"
    
    # Store image in a temp folder
    file_path = Tempfile.new(["file", '.jpg']).path
    kit.to_file(file_path)
    
    # Upload the image
    user.profile.avatar.attach(io: File.open(file_path), filename: 'avatar.jpg')
  end
end

```

## The Flow
During user registration, `random_colour` is used to set a random colour. Next, we call `generate_avatar(resource)` to generate and upload the image. You would call `generate_avatar` every time the user changes their name 😉

Feel free to to modify the font size and dimensions for the image. Enjoy!