- Gemfile (bundle install)
```ruby
gem 'faker', :git => 'https://github.com/faker-ruby/faker.git', :branch => 'master' # optional!!! (only for use in seed.rb)
gem 'faraday' # optional!!! (only for use in seed.rb)
gem 'gravatar_image_tag', github: 'secretpray/gravatar_image_tag', branch: 'master'
gem 'hotwire-rails' # optional!!!
gem 'image_processing', '~> 1.2'
gem 'tailwindcss-rails', '~> 0.5.1' # optional!!!
```
2) Sample view template
~~~~~~~~~~~~~~~~~~~~~~~
```
<span class='text-gray-400 transform transition duration-300 hover:scale-110 cursor-pointer'>
<%= link_to account_path(current_user), data: { turbo: "false" } do %>
<%= user_avatar(current_user, 40) %>
<% end %>
</span>
```
PS To use current_user check for installed gem Devise with model User and Active Storage!!!
3) app/helpers/users_helper.rb
module UsersHelper
def user_avatar(user, size=40)
# if user.avatar.attached?
if user.respond_to?(:avatar) && user.avatar.attached? && user.avatar.variable?
image_tag user.avatar.variant(resize: "#{size}x#{size}!"), class: 'rounded-full'
else
avatar_circle(user, size)
# gravatar_image_url(user.email, size: size)
end
end
def avatar_circle(user, size)
if gravatar_exists?(user.email)
image_tag gravatar_image_url(user.email, size: size), class: 'rounded-full'
# gravatar_id = Digest::MD5.hexdigest(user.email)
# gravatar_url = "https://secure.gravatar.com/avatar/#{gravatar_id}"
# image_tag(gravatar_url, class: 'avatar_circle')
else
# inline_svg_pack_tag('media/images/user.svg', class: "rounded", size: "5rem * 5rem")
initials = [user.first_name&.first, user.last_name&.first].join('')
initials = user.email.gsub(/[[-.][_.]]+/, '').first(2) if initials.blank?
style = "background-color: #{avatar_color(initials)}; height: #{size}px; width: #{size}px;"
content_tag :div, class: 'avatar-circle', style: style do
content_tag :div, initials, class: 'avatar-text'
end
end
end
def gravatar_exists?(email)
hash = Digest::MD5.hexdigest(email)
http = Net::HTTP.new('www.gravatar.com', 80)
http.read_timeout = 2
response = http.request_head("/avatar/#{hash}?default=http://gravatar.com/avatar")
response.code != '302' ? true : false
rescue StandardError, Timeout::Error
false
end
def avatar_color(initials)
colors = [
'#00AA55', '#009FD4', '#B381B3', '#939393', '#E3BC00',
'#047500', '#DC2A2A', '#696969', '#ff0000', '#ff80ed',
'#407294', '#133337', '#065535', '#c0c0c0', '#5ac18e',
'#666666', '#f7347a', '#576675', '#696966', '#008080',
'#ffa500', '#40e0d0', '#8000ff', '#003366', '#fa8072',
'#800000'
]
colors[initials.first.to_s.downcase.ord - 97] || '#000000'
end
end
- app/models/user.rb
```ruby
class User < ApplicationRecord
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable
has_one_attached :avatar
end
```
5) app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
before_action :configure_permitted_parameters, if: :devise_controller?
protected
def configure_permitted_parameters
added_attrs = [:avatar]
devise_parameter_sanitizer.permit(:sign_up, keys: added_attrs)
devise_parameter_sanitizer.permit(:account_update, keys: added_attrs)
end
end
- app/assets/stylesheets/user.scss
```html
.avatar-circle {
display: inline-block;
width: 40px;
height: 40px;
border-radius: 50%;
position: relative;
}
.avatar-text {
color: #fff;
text-transform: uppercase;
transform: translate(-50%, -50%);
left: 50%;
top: 50%;
position: absolute;
}
```
_ Optional part _
db/seeds.rb
~~~~~~~~~~~
```ruby
require 'open-uri'
require 'faraday'
require 'json'
Post.destroy_all
User.destroy_all
DEFAULT_MALE_IMAGE_URL = 'https://randomuser.me/api/portraits/men/43.jpg'
DEFAULT_FEMALE_IMAGE_URL = 'https://randomuser.me/api/portraits/women/49.jpg'
MAX_MALES = 7
MAX_FEMALES = 8
puts 'Please wait while get seed data!'
admin = User.where(email: '[email protected]', first_name: 'Aleksey', last_name: 'Reznov').first_or_initialize
admin.update(password: 'password') if admin.new_record?
# Star Wars heroes
response = Faraday.get('https://akabab.github.io/starwars-api/api/all.json')
data = JSON.parse(response.body)
# sleep 1
males, females = data.partition { |hero| hero['gender'] == 'male' }
males = males.sample(MAX_MALES) # limit users => 15
females = females.sample(MAX_FEMALES)
def set_email(hero)
"#{hero['name'].parameterize.underscore}@starwars.com"
end
def set_url(gender)
gender == 'male' ? DEFAULT_MALE_IMAGE_URL : DEFAULT_FEMALE_IMAGE_URL
end
def create_avatar(user, gender, url = nil)
url = set_url(gender) if url.nil?
downloaded_image = URI.parse(url).open rescue nil # check bad image URL: "[email protected]" - 404
if downloaded_image.nil?
downloaded_image = URI.parse(set_url(gender)).open rescue nil
end
return if downloaded_image.nil?
user.avatar.attach(io: downloaded_image, filename: user.email)
end
def create_user(hero)
hero_email = set_email(hero)
first_name_hero, *last_name_hero = hero['name'].split(' ')
last_name_hero = last_name_hero.join(' ') if last_name_hero.is_a?(Array)
user = User.create!(email: hero_email,
first_name: first_name_hero,
last_name: last_name_hero,
password: 'password')
create_avatar(user, hero['gender'], hero['image'])
print('.')
end
print "Create users."
males.each { |hero| create_user(hero) }
females.each { |hero| create_user(hero) }
puts "All Ok!"
puts "Created #{User.count} users!"
```
Presenters
All remove -> empty file