#Avatar with gem paperclip http://www.peoplecancode.com/en/tutorials/users-avatars-uploading-images-using-paperclip
https://github.com/thoughtbot/paperclip
##Задача - сделать аватар для пользователей Сначала устанавливаем гем paperclip в Gemfile проекта
gem 'paperclip', '~> 4.3'
делаем bundle install
затем в терминале в папке с проектом пишем rails generate migration add_avatars_to_users, которая создаст файл в папке db/migrate//20140516064357_add_avatars_to_users.rb
заходим в него и заполняем кодом:
db/migrate/20140516064357_add_avatars_to_users.rb
class AddAvatarsToUsers < ActiveRecord::Migration
def self.up
change_table :users do |t|
t.attachment :avatar
end
end
def self.down
drop_attached_file :users, :avatar
end
end
затем в терминале в папке с проектом пишем rake db:migrate
заходим в модель user.rb и пишем
class User < ActiveRecord::Base
# existing code
has_attached_file :avatar, :styles => { :medium => "300x300>", :thumb => "100x100#" }, :default_url => "/images/:style/missing.png"
validates_attachment_content_type :avatar, :content_type => /\Aimage\/.*\Z/
end
создаем в папке public папки с файлами images/medium/missing.png images/thumb/missing.png
добавляем :avatar in permit params
def update
@user = current_user
avatar = user_params_for_avatar
@res = @user.update(avatar)
respond_to do |format|
if @res
format.html {
redirect_to profileshow_path, notice: 'User was successfully updated'
}
#format.json { render :show, status: :ok, location: @user }
else
format.html { render :edit }
#format.json { render json: @user.errors, status: :unprocessable_entity }
end
end
def user_params_for_avatar
params.require(:user).permit(:avatar)
end
для show.htm.haml можем использовать на выбор:
= image_tag avatar_url(@user)
метод avatar_url мы определяем в хэлпере
/../app/helpers/application_helper.rb
module ApplicationHelper
def avatar_url(user)
if user.avatar.present?
user.avatar.url(:medium)
else
gravatar_id = Digest::MD5.hexdigest(user.email.downcase)
"http://gravatar.com/avatar/#{gravatar_id}.png?s=100&d=identicon"
end
end
end
в форме _form.html.haml
= horizontal_simple_form_for(@user, :url => profileupdate_path, :method => :put, :html => { :multipart => true}) do |f|
-#= f.error_notification
= render 'shared/form_errors', {f: f}
= f.input :avatar, as: :file
https://github.com/thoughtbot/paperclip#uri-obfuscation
http://stackoverflow.com/questions/7593548/paperclip-converting-tiff-images-into-jpg-or-png
../models/user.rb
class User < ActiveRecord::Base
has_attached_file :avatar, {
url: "/users/:attachment/:id_partition/:style/:hash.:extension",
hash_secret: "BlaBlaBla",
:styles => {
:thumb => ["150x172#",:jpg],
:medium => ["300x300#",:jpg],
:large => ["100%", :jpg]
}
}
validates_attachment_content_type :avatar, :content_type => /\Aimage\/.*\Z/
...some code here
end
url: "/users/:attachment/:id_partition/:style/:hash.:extension", сохраняет в папку public, создавая директорию users/avatars/000/000/папка с номером id в базе данных с папками для каждого из ключей хэша (thumb, medium, large) и соответствующим каждому ключу файлами в этих папках с расширением файла, написанным в хэше.
hash_secret: "BlaBlaBla", шифрует название файла для отображения в браузере (например загружаемый файл flower.jpg в браузере будет называться 038974650239487523489570293645.jpg). В базу заносится название файла, загружаемое юзером (flower.jpg)
"300x300#" - точный размер "300x300>" - не обрезает
http://guides.railsgirls.com/gravatar/
http://railscasts.com/episodes/244-gravatar?autoplay=true
https://github.com/chrislloyd/gravtastic
http://en.gravatar.com/site/implement/images/
в Gemfile добавляем gem 'gravtastic' делаем bundle install
добавляем в модель user.rb
class User < ActiveRecord::Base
include Gravtastic
gravtastic
end
теперь во вьюхе мы можем использовать = image_tag @user.gravatar_url
в application_helper.rb (см. выше) код в методе avatar_url
...
gravatar_id = Digest::MD5.hexdigest(user.email.downcase)
"http://gravatar.com/avatar/#{gravatar_id}.png?s=100&d=identicon"
дает нам возможность генерировать рандомные аватарки по ключу user.email, если в базе для данного юзера нет аватарки, то генерится рандомная identicon
также можно воспользоваться другими шаблонами для создания рандомных аватарок:
404: do not load any image if none is associated with the email hash, instead return an HTTP 404 (File Not Found) response
mm: (mystery-man) a simple, cartoon-style silhouetted outline of a person (does not vary by email hash)
identicon: a geometric pattern based on an email hash
monsterid: a generated 'monster' with different colors, faces, etc
wavatar: generated faces with differing features and backgrounds
retro: awesome generated, 8-bit arcade-style pixelated faces
blank: a transparent PNG image (border added to HTML below for demonstration purposes)
http://stackoverflow.com/questions/8789820/rounded-corners-with-paperclip
http://www.imagemagick.org/Usage/thumbnails/#rounded
для содания любых форм и рамок для аватарки можно воспользоваться примером из ссылки выше.
задача - сделать круглую аватарку
для этого создаем метод convert_options в модели и подправляем styles в параметрах метода has_attached_file в модели user.rb
../models/user.rb
class User < ActiveRecord::Base
has_attached_file :avatar, {
url: "/users/:attachment/:id_partition/:style/:hash.:extension",
hash_secret: "BlaBlaBla",
:styles => {
:thumb => ["100x100#",:jpg],
:medium => ["300x300#",:png],
:original => ["100%", :jpg],
},
:convert_options => {:medium => Proc.new{self.convert_options}}
}
def self.convert_options(px = 150)
trans = ""
trans << " \\( +clone -alpha extract "
trans << "-draw 'fill black polygon 0,0 0,#{px} #{px},0 fill white circle #{px},#{px} #{px},0' "
trans << "\\( +clone -flip \\) -compose Multiply -composite "
trans << "\\( +clone -flop \\) -compose Multiply -composite "
trans << "\\) -alpha off -compose CopyOpacity -composite "
end
ВАЖНО!!!
расширение изменяемого файла нужно ставить .png, как здесь :medium => ["300x300#",:png]
../app/models/product_document.rb
class ProductDocument < ActiveRecord::Base
belongs_to :product, class_name: "Product", foreign_key: 'product_id'
has_attached_file :doc,
styles:{},
url: "/docs/:id_partition/:basename.:extension"
do_not_validate_attachment_file_type :doc
end
../app/controllers/product_documents_controller.rb
class Admin::ProductDocumentsController < Admin::MyAdminBaseController
def model_name
:product_document
end
def index
@product = Product.find(params[:product_id])
@items = @product.documents
end
def item_params
params.require(model_name).permit(:doc)
end
end
../app/views/product_documents/_form.html.haml
= horizontal_simple_form_for([:admin, @item], html: { class: 'form-horizontal' }) do |f|
= f.error_notification
= f.input :doc, as: :file
../app/views/product_documents/_form.html.haml
%table.table.table-striped.table-bordered.table-hover
%tr
%th File
- @items.each do |item|
%tr
%td
- if item.doc.exists?
= link_to "#{item.doc.url}", item.doc.url, target: "_blank"
- else
N/A