Avatar - Subir imágenes con Paperclip

Por:, en:

ES:This tutorial assumes you have already completed:

  1. Styling Devise forms with TwitterBootstrap
  2. Adding custom fields to Devise

Después de haber creado a nuestros usuarios, ahora es tiempo de permitirles subir sus propios avatares y eventualmente algunas otras imágenes que les gustaría compartir.

Dado que trabajamos Heroku.com como una plataforma para desplegar, habrá algunas medidas adicionales que tenemos que realizar (en el siguiente tutorial).

Añadir Vamos a hacer lo siguiente:

  1. Añadir la gema clip
  2. Añadir el avatar al modelo de usuario
  3. Añadir el avatar y subir los formularios de Devise

¡Empecemos!

Paso 1: Añade la Gema Paperclip

Hay dos formas para subir imágenes en las aplicaciones de Rails. Algunas personas usan Paperclip y otras usan RSolr. Utilizaremos Paperclip en este tutorial..

En primer lugar, visita Paperclip documentation y échale un vistazo, utilizaremos algunas de las instrucciones que aparecen allí. También puedes checar los ajustes adicionales disponibles para la gema.

Vamos a empezar por instalar el procesador de imagen – ImageMagick. Este se encargará de manipular nuestras imágenes, redimensionar, recortar, etc. Abre la terminal y escribe si usas Mac:

bash


$ brew install imagemagick

Si usas Linux, escribe:

bash


$ sudo-apt-get install imagemagick

Paso 1.2

Ahora, necesitamos agregar Paperclip en el Gemfile

Gemfile


source 'https://rubygems.org'

# existing gems

gem 'paperclip', '~> 4.1'

Paso1.3

y ahora agrupa la gema:

bash


$ bundle install

Paso 2: Añade Avatar al usuario modelo

Permítanme comenzar con una pequeña explicación. Cuando subes imágenes, realmente no las guardas en la base de datos. Nuestra base de datos no puede contener ningún archivo. Así que lo que haremos, o más bien lo que paperclip hara, sera guardar las imágenes en una carpeta designada. ¿Cómo podemos encontrar donde está el avatar del usuario? Para ello necesitamos un lugar en la base de datos para almacenar cosas como nombres de archivo o tamaños. En una página de Github encontrarás un comando para generar automáticamente la migración, pero recientemente he estado teniendo problemas con él, por lo tanto generaremos migración a mano. En el terminal, escribe:

bash


$ rails generate migration add_avatars_to_users

      invoke  active_record
      create    db/migrate/20140516064357_add_avatars_to_users.rb

Paso 2.2

A continuación, abre el archivo de migración y pega el código que añadirá el avatar en el modelo de usuario:

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

Paso 2.3

Y migra la base de datos en tu terminal:

bash


$ rake db:migrate

Paso 2.4

Ahora, lo que queda es la declaración en el archivo de modelo para saber que puedes tener un archivo adjunto..


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

Hay un par de cosas que tuvimos que hacer aquí. En primer lugar, declaramos que hay un archivo adjunto en el modelo de usuario y lo llamamos "avatar". Si lo llamáramos diferentemente, por ejemplo "imagen", entonces tendríamos que cambiar el nombre anterior por “imagen”.

En segundo lugar, declaramos dos estilos para las imágenes y los llamamos medium (medio) y thumb (pulgar). Podríamos agregar más estilos o tener menos. Realmente todo depende de lo que quieran nuestros usuarios. Queremos enviar archivos lo más pequeños posibles para que todo trabaje más rápido, pero al mismo tiempo queremos que las imágenes tengan buena calidad. Si estás planeando tener fotos de perfiles más grandes, tal vez consideres cambiar las dimensiones. "300 x 300 >" significa que si la imagen es mayor que 300 por 300 píxeles, proporcionaremos la escala y guardaremos las dimensiones para que no excedan a más de 300 píxeles. Si queremos recortar fotos para que se vean cuadradas - escribiríamos "300 x 300#".

Por último, es la URL estándar. Esta es la imagen que será servida si nuestro avatar no está presente. Tal vez el usuario todavía no sube su foto, o tal vez hubo un error durante la carga. Necesitamos asegurarnos de que nuestra imagen está en la ubicación correcta. De forma estándar los carriles quedaran en carpetas públicas. Así que, si la versión del archivo "thumb” no está presente - nos mostrará la imagen en el archivo public/images/thumb/missing.png .

Dentro de la carpeta de imáges, necesitamos más carpetas: una llamada "thumb" y la otra "medium". Ambas deben contener un archivo llamado "missing.png". En el archivo thumb, la imagen sera la imagen de 100 por 100 píxeles y en el medium sera la imagen de 300 por 300.

success after uploading avatar

También se incluyó una validación. Sin esta línea, nuestra carga no funcionará. La validación es una característica de seguridad que impide el envío de archivos maliciosos.

¡Muy bien! nuestro sitio web ya puede manejar las imágenes, pero todavía no tenemos forma de presentar imágenes desde la interfaz de usuario.

Paso 2.5

Desde que estamos usando Devise para administrar a nuestros usuarios, tendremos que asegurarnos de que Device permite nuestro nuevo avatar. Si aún no lo has hecho, échale un vistazo al tutorial sobre  custom fields when using devise.

app/controllers/application_controller.rb


class ApplicationController < ActionController::Base
    # Prevent CSRF attacks by raising an exception.
    # For APIs, you may want to use :null_session instead.
    protect_from_forgery with: :exception
    before_filter :configure_permitted_parameters, if: :devise_controller?

    protected

    def configure_permitted_parameters
        devise_parameter_sanitizer.for(:sign_up) { |u| u.permit(:name, :email, :password) }
        devise_parameter_sanitizer.for(:account_update) { |u| u.permit(:name, :email, :password, :current_password, :is_female, :date_of_birth, :avatar) }
    end
end

Paso 3: Añade “Avatar upload” para los formularios de Device

El último paso para ver la descarga trabajo es agregar un campo de carga de archivos a registrations:

app/views/users/registrations/edit.html.erb


    <h2>Edit <%= resource_name.to_s.humanize %></h2>

    <%= form_for(resource, as: resource_name, url: registration_path(resource_name), html: { method: :put, class: 'form-horizontal' }) do |f| %>
    <%= devise_error_messages! %>

    <div class="form-group">
        <%= f.label :avatar, class: 'col-sm-2 control-label'  %>
        <div class="col-sm-6">
            <%= f.file_field :avatar %>
        </div>
    </div>


    <div class="form-group">
        <%= f.label :name, class: 'col-sm-2 control-label'  %>
        <div class="col-sm-6">
            <%= f.text_field :name, autofocus: true, class: 'form-control'  %>
        </div>
    </div>

    <div class="form-group">
        <%= f.label :is_female, "Gender", class: 'col-sm-2 control-label'  %>
        <div class="col-sm-6">
            <%= f.radio_button :is_female, true %> <%= f.label :is_female, "Female" %>
            <%= f.radio_button :is_female, false %> <%= f.label :is_female, "Male" %>
        </div>
    </div>


    <div class="form-group">
        <%= f.label :date_of_birth, class: 'col-sm-2 control-label'  %>
        <div class="col-sm-6">
            <%= f.date_select :date_of_birth, start_year: 1920, end_year: 2000, class: 'form-control'  %>
        </div>
    </div>

    <div class="form-group">
        <%= f.label :email, class: 'col-sm-2 control-label'  %>
        <div class="col-sm-6">
            <%= f.email_field :email, class: 'form-control'  %>
        </div>
    </div>

    <div class="form-group">
        <%= f.label :password, class: 'col-sm-2 control-label'  %> <i>(leave blank if you don't want to change it)</i>
        <div class="col-sm-6">
            <%= f.password_field :password, autocomplete: "off", class: 'form-control'  %>
        </div>
    </div>


    <div class="form-group">
        <%= f.label :password_confirmation, class: 'col-sm-2 control-label' %>
        <div class="col-sm-6">
            <%= f.password_field :password_confirmation, autocomplete: "off", class: 'form-control'  %>
        </div>
    </div>

    <div class="form-group">
        <%= f.label :current_password, class: 'col-sm-2 control-label' %> <i>(we need your current password to confirm your changes)</i>
        <div class="col-sm-6">
            <%= f.password_field :current_password, autocomplete: "off", class: 'form-control' %>
        </div>
    </div>

    <div class="form-group">
        <div class="col-sm-offset-2 col-sm-6">
            <%= f.submit "Update", class: "btn btn-primary" %>
        </div>
    </div>

    <div class="form-group">
        <div class="col-sm-offset-2 col-sm-6">
            <%= render "users/shared/links" %>
        </div>
    </div>
    <% end %>

    <h5>Cancel my account</h5>

    <p>Unhappy? <%= button_to "Cancel my account", registration_path(resource_name), data: { confirm: "Are you sure?" }, method: :delete, class: 'btn btn-default btn-xs' %></p>

    <%= link_to "Back", :back %>

Nuestra edición de perfil (http://localhost:3000/usuarios/editar) deberá de verse así:

form for uploading user's avatars

Después de cargar con éxito el avatar, verás un aviso:

success after uploading avatar

Paso 3.2

Desafortunadamente, aún no podemos mostrar los avatares de los usuarios en cualquier parte. Vamos a arreglarlo:

app/views/layouts/_menu.html.erb


    <div class="collapse navbar-collapse" id="navbar-collapse-1">
        <ul class="nav navbar-nav navbar-right">
            <li><%= link_to 'Posts', '#' %></li>
            <% if current_user %>
            <li><%= link_to 'Edit Profile',edit_user_registration_path %></li>
            <li><%= link_to 'Logout', destroy_user_session_path, method: :delete %></li>

            <li class="round-image-50"><%= image_tag(current_user.avatar.url(:thumb)) %></li>

            <% else %>
            <li><%= link_to 'Login', new_user_session_path %></li>
            <% end %>
        </ul>
    </div>

Paso 3.3

Y dale estilo usando CSS:

app/assets/stylesheets/custom.css.scss


.round-image-50 {
    background-color: white;
    border: 1px solid #d9d9d9;
    border-radius: 25px;
    -moz-border-radius: 25px;
    -webkit-border-radius: 25px;
    height: 50px;
    width: 50px;
    overflow: hidden;
    text-align: center;
    img { width: 100% }
}

Ahora, puedes ver tu avatar en el menú:

success after uploading avatar

Si tu Inicio de sesión serás capaz de marcar esto tutorial Como vas avanzando tu progreso



Comentarios

  • en: mohammad javad escribió:

    my image_tag(current_user...) does not work properly and it just shows missing picture?

  • en: mohammad javad escribió:

    i'm getting this error when uploading picture : Avatar has an extension that does not match its contents

  • en: Jose Pejuan escribió:

    This line right here: <%= imagetag(currentuser.avatar.url(:thumb)) %> its throwing me an error. Says the method doesn't exist

Comentar

Tú puedes Inicio de sesión Comentar