Listado de usuarios - Perfil e índice de perfiles

Por:, en:

ES:This tutorial assumes you have already completed:

  1. Adding custom fields to devise

Ahora nuestros usuarios pueden registrarse. Sin embargo, los usuarios no pueden interactuar entre sí. Si estamos considerando alguna característica o colaboración social, en algún momento tendremos que permitir a los usuarios ver los perfiles de otros. En este tutorial, vamos a trabajar en la creación del índice de usuarios y sus páginas individuales.

  • Índice del usuario
  • Perfiles de usuarios

Paso 1: Crea el índice de Usuarios

Previamente, creamos páginas (static pages) en controller.rb. Este contenía algunas acciones personalizadas como "home" o "contact". En el caso de nuestros usuarios, recurriremos a un enfoque más estándar que llamamos API REST. La primera vez que leí este nombre, me dio escalofríos de pensar que era algo realmente difícil. Pero no, en realidad es un concepto bastante simple. API significa Interfaz de programación de aplicaciones (Application Programming Interface). API REST, es una forma estándar para pedir información a nuestro servidor (o enviar información al servidor) mediante el uso de URL. No cualquier URL, pero el estándar. En el Tutorial about creating posts in blogging application tutorial tiene más información sobre este tema.

Paso 1.2: Crea el controlador

Empieza creando el controlador para manipular a nuestros usuarios.

bash


$ rails generate controller users


    create  app/controllers/users_controller.rb
    invoke  erb
    exist    app/views/users
    invoke  test_unit
    create    test/controllers/users_controller_test.rb
    invoke  helper
    create    app/helpers/users_helper.rb
    invoke    test_unit
    create      test/helpers/users_helper_test.rb
    invoke  assets
    invoke    coffee
    create      app/assets/javascripts/users.js.coffee
    invoke    scss
    create      app/assets/stylesheets/users.css.scss

Abre el controlador que acabamos de crear y échale un vistazo:

app/controllers/users_controller.rb


class UsersController < ApplicationController
end

Paso 1.3: Crea la acción Índex

Iniciaremos mediante la creación de medidas de índice para mostrar a todos los usuarios registrados en nuestro sitio Web. Agrega los siguientes cambios:

app/controllers/users_controller.rb


class UsersController < ApplicationController
  def index
    @users = User.all
  end
end

Paso 1.4: Crea el archivo HTML

Ahora podemos proceder con la creación de la plantilla HTML para nuestro índice. Crea un nuevo archivo dentro de app/views/users, llámalo con el mismo nombre que el de nuestra acción -- index.html.erb y agrega el código siguiente:

app/views/users/index.html.erb


<ul>
    <% @users.each do |user| %>
        <li><%= user.email %></li>
    <% end %>
</ul>

Paso 1.5: Cambia las rutas de archivo

A fin de poder abrir esta página, tenemos que modificar nuestro archivo routes.rb para que la aplicación sepa cómo asignar URL y el controlador:para que la aplicación sepa cómo asignar URL y el controlador:

config/routes.rb


devise_for :users

resources :users, only: [:index, :show]

#codigo existente

Inicia tu aplicación y ve al http://localhost:3000/users

Deberás de ver una lista de todos los usuarios registrados en tu aplicación.

Paso 1.6: Añade los enlaces

También queremos añadir los enlaces en el menú para alcanzar el índice:

app/views/layouts/_menu.html.erb


<nav class="navbar navbar-default" role="navigation">
    <div class="container">

        <div class="navbar-header">
            <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#navbar-collapse-1">
                <span class="sr-only">Toggle navigation</span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
            </button>
            <%= link_to "Demo App", root_path, class: 'navbar-brand' %>
        </div>

        <div class="collapse navbar-collapse" id="navbar-collapse-1">
            <ul class="nav navbar-nav navbar-right">

                <li><%= link_to 'Members', users_path %></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>
    </div>
</nav>

Paso 2: Crea los perfiles de los usuarios

Después de haber creado una manera de ver la lista de todos los usuarios, ahora queremos ver sus perfiles. Crearemos una nueva acción en el users controller y lo llamaremos “show”:

app/controllers/users_controller.rb


class UsersController < ApplicationController
  # codigo existente

  def show
    @user = User.find(params[:id])
  end

end

Paso 2.2: Crea una plantilla

Y ahora crea una plantilla igual dentro de app/views/users:

app/views/users/show.html.erb


<h1><%= @user.email %></h1>
<ul>
    <li>Name: <%= @user.name %></li>
    <li>Date of birth:<%= @user.date_of_birth %></li>
</ul>

Paso 2.3: Reemplaza los e-mails en el índice por Enlaces

A fin de llegar fácilmente a esta página, debemos de cambiar nuestro índice de correos a una lista de enlaces que conducen a los perfiles:

app/views/users/index.html.erb


<ul>
    <% @users.each do |user| %>
        <li><%= link_to user.email, user_path(user) %></li>
    <% end %>
</ul>

Paso 3: Refinación

En este momento, todo debe de funcionar. Sin embargo, podrías notar que los perfiles y el índice necesitan un poco de pulido. Haremos los siguientes cambios:

  • En vez de usar el correo electrónico, usaremos el nombre del usuario
  • Si alguna información no está presente, no lo mostraremos
  • En vez de la fecha de nacimiento, mostraremos la edad

Abordaremos uno por uno.

Paso 3.2: Remplaza el correo electrónico por el nombre

Desde el principio que creamos los usuarios con Device, no usamos sus nombre. Los nombres lo añadimos después. Todavía no requerimos a nuestros usuarios usar su nombre. Lo pueden hacer, pero no es obligatorio. Por lo tanto, nos estamos quedando con un riesgo: cuando el usuario no ponga su nombre, habrá un espacio vacío. Para evitar esto, escribiremos un "método de instancia" para la class del usuario. Vamos a escribir el código y discutir lo que hace:

app/models/user.rb


class User < ActiveRecord::Base

  #codigo existente

  def full_name
    if self.name.blank?
      self.email
    else
      self.name
    end
  end

end

Con este método podemos tomar "instance" de una clase de usuario (ex. current_user) y ejecutar el comando .full_name command on it. . Esto devolverá el nombre, si el nombre no está en blanco, y si esta aparecerá el correo electrónico. Hay una forma más concisa de escribirlo utilizando "terninary operator". Puede ser un poco confuso, así que antes de usarlo, asegúrate de que entiendes cómo funciona. Además, usando 'self' es opcional, yo lo uso para mayor claridad. El código siguiente es sólo otro ejemplo.

app/models/user.rb


def full_name
    name.blank? ? email : name
end

Paso 3.3: Muestra sólo los registros que no está vacíos

En el perfil del usuario intentamos mostrar su nombre y la fecha de nacimiento. Pero ¿qué pasa si el usuario no llena esta información? Necesitamos una forma de esconder estos registros, de lo contrario, nuestro sitio web no será muy presentable. Técnicamente, podríamos escribir algo como esto:

app/views/users/show.html.erb


<h1><%= @user.email %></h1>
<ul>
    <% unless @user.name.blank? %>
        <li>Name: <%= @user.name %></li>
    <% end %>

    <% unless @user.date_of_birth.blank? %>
        <li>Date of birth:<%= @user.date_of_birth %></li>
    <% end %>
</ul>

Afortunadamente, lo podemos escribir de forma más concisa mediante content_tag:

app/views/users/show.html.erb


<h1><%= @user.email %></h1>
<ul>
    <%= content_tag(:li, ("Name: " + @user.name)) unless @user.name.blank? %>
    <%= content_tag(:li, ("Date of birth: " + @user.date_of_birth)) unless @user.date_of_birth.blank? %>
</ul>

Hicimos esto porque no queremos mostrar todo el tag  "li" cuando no hay contenido.

Paso 3.4: Remplaza la edad por la fecha de nacimiento

Aquí usaremos “la magia de Rails”:

app/views/users/show.html.erb


<h1><%= @user.email %></h1>
<ul>
    <%= content_tag(:li, ("Name: " + @user.name)) unless @user.name.blank? %>
    <%= content_tag(:li, ("Age: " + distance_of_time_in_words(Time.now, @user.date_of_birth) + " old")) unless @user.date_of_birth.blank? %>
</ul>

Observa cómo usamos "distance_of_time_in_words(one_date, other_date)"

Dentro de nuestro HTML tenemos un Ruby muy complejo. Rara vez, Ruby es más complicado que este código.

Paso 4: Haz que la página se vea mejor

Te quiero dejar el diseño a ti, pero te ayudare a empezar con un poco de responsivo diseño básico. Cambia el tamaño de la ventana para ver cómo funciona.

app/views/users/index.html.erb


<div class="container">
    <div class="users row">
        <% @users.each do |user| %>
        <div class="panel panel-default">
            <%= link_to user_path(user) do %>
            <div class="panel-body">
                <%= image_tag(user.avatar.url(:medium)) %>
                <p><%= user.full_name %></p>
            </div>
            <% end %>
        </div>
        <% end %>
    </div>
</div>

app/views/users/show.html.erb


<div class="row profile">
    <div class="col-sm-4 col-md-3">
        <%= image_tag(@user.avatar.url(:medium), class: 'avatar') %>
        <h1><%= @user.full_name %></h1>
        <ul>
            <%= content_tag(:li, ("Name: " + @user.name)) unless @user.name.blank? %>
            <%= content_tag(:li, ("Age: " + distance_of_time_in_words(Time.now, @user.date_of_birth) + " old")) unless @user.date_of_birth.blank? %>
        </ul>
    </div>
    <div class="feed">
        <h3>Social Feed Coming</h3>
        <p>Put a couple of lines of text here and see how it scrolls</p>
    </div>
</div>

app/assets/stylesheets/custom.css.scss


// Columns

.users.row {
    -moz-column-width: 15em;
    -webkit-column-width: 15em;
    -moz-column-gap: 0;
    -webkit-column-gap: 0;
}

@media (min-width: 992px) {
    .users.row {
        -moz-column-width: 13.5em;
        -webkit-column-width: 13.5em;
    }
}


// users index

.feed {
    width: 100%;
    text-align: center;
}

.panel {
    display: inline-block;
    padding:  0;
    margin:  0 0 10px 0;
    width:98%;
    img { width: 100%; }
}

    // users show

.profile {
    text-align: center;
    .avatar { max-width: 100%; }
    ul {
        list-style: none;
        padding: 0;
    }
}

.users .panel-body {
    padding: 0;
    p {
        margin: 10px;
        overflow-x: scroll;
    }
   &:hover {
        background-color: #fcfcfc;
        box-shadow: 0 0 3px #b7b7b7;
    }
}


@media (min-width: 768px) {
    .feed {
        text-align: center;
        position: absolute;
        right: 0;
        top:53px;
        bottom:0;
        border-left: 1px dotted #e4e4e4;
        width: 63%;
        overflow-y: scroll;
        padding-top: 50px;
    }
    .profile {text-align: left}
}

Debería de verse más o menos así:

Índice de perfiles

Index of users

Perfil de usuarios

User's profile

Paso 4.2: Añade JQuery y arregla CSS

Una cosa más, que tenemos que recordar aquí, es porque estamos usando position: absolute; esto interferirá con nuestros mensajes flash, que por el momento aparecen encima del menú. Podemos arreglarlo fácilmente con un poco de jQuery. Vamos a añadir un pequeño código a los mensajes flash:

app/views/layouts/_flash_messages.html.erb


<% flash.each do |key, value| %>
    <div class="alert alert-<%= key %> alert-dismissable">
        <button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
        <%= value %>
    </div>
<% end %>


<script>
    $('.alert').fadeOut(4000);
</script>

Y cambia el CSS:

app/assets/stylesheets/custom.css



$navbar-default-border: #e5e5e5;
$navbar-margin-bottom: 50px;

@import "bootstrap";

.field_with_errors { @extend .has-error; }
.alert-notice { @extend .alert-info; }
.alert-alert { @extend .alert-danger; }

.alert {
   top: 50px;
   left:0;
   right: 0;
   position:absolute;
}

// codigo existente
 

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



Comentarios

  • en: Mohamed Saleem escribió:

    This was one amazing tutorial for me. I have been searching something like this for a long time. Thanks you very much..
  • en: Brunitob escribió:

    There is a ";", you need to remove it. Then its perfect

    .users .panel-body {
    padding: 0;
    p {
        margin: 10px;
        overflow-x: scroll;
    }
    &;:hover {
        background-color: #fcfcfc;
        box-shadow: 0 0 3px #b7b7b7;
    }
    

    }

  • en: Brunitob escribió:

    Before hover.

  • en: Muzyka Bartek escribió:

    Thanks! Already fixed.

Comentar

Tú puedes Inicio de sesión Comentar