Biblioteca UCE - Universidad Central del Ecuador

Anuncio
UNIVERSIDAD CENTRAL DEL ECUADOR
FACULTAD DE INGENIERÍA EN CIENCIAS FÍSICAS Y
MATEMÁTICA
CARRERA DE INGENIERÍA INFORMÁTICA
ANÁLISIS DESCRIPTIVO DE LA TECNOLOGÍA RUBY ON RAILS PARA EL
DESARROLLO DE PÁGINAS WEB
TRABAJO DE GRADUACIÓN PREVIO A LA OBTENCIÓN DEL TÍTULO DE
INGENIERO INFORMÁTICO
AUTOR: ALEX FERNANDO PICO COBA
TUTOR: M.Sc. RENÉ ALFONSO CARRILLO FLORES
QUITO – 24 DE MAYO
2016
DEDICATORIA
A mi madre
Martha Coba
con cariño.
ii
AUTORIZACIÓN DE LA AUTORÍA INTELECTUAL
Yo Alex Fernando Pico Coba en calidad de autor del trabajo de investigación: “Análisis
descriptivo de la tecnología Ruby on Rails para el desarrollo de páginas web”, autorizo a
la Universidad Central del Ecuador hacer uso de todos los contenidos que me pertenecen
o parte de los que contiene esta obra, con fines estrictamente académicos o de
investigación.
Los derechos que como autores me corresponden, con excepción de la presente
autorización, seguirán vigentes a mi favor, de conformidad con lo establecido en los
artículos 5, 6, 8; 19 y demás pertinentes de la Ley de Propiedad Intelectual y su
Reglamento.
Así mismo, autorizo a la Universidad Central del Ecuador para que realice la digitalización
y publicación de este trabajo de investigación en el repositorio virtual, de conformidad a lo
dispuesto en el Art. 144 de la Ley Orgánica de Educación Superior.
En la ciudad de Quito, a los días 23 del mes mayo de 2016
Alex Fernando Pico Coba
CC: 1803990397
Telf: 0984141535
Dirección electrónica: [email protected]
iii
CERTIFICACIÓN DEL TUTOR
Yo, Rene Alfonso Carrillo Flores en calidad de tutor del trabajo de titulación: “Análisis
Descriptivo de la Tecnología Ruby on Rails para el Desarrollo de Páginas Web”,
elaborado por el estudiante de la Carrera de Ingeniería Informática, Facultad de Ciencias
Físicas y Matemática de la Universidad Central de Ecuador, considero que el mismo
reúne los requisitos y méritos en el campo metodológico, para ser sometido a la
evaluación por parte del jurado examinador que se designe por lo que lo APRUEBO, a fin
de que el trabajo investigativo sea habilitado para continuar con el proceso de titulación
determinado por la Universidad Central del Ecuador.
En la ciudad de Quito, a los días 01 del mes abril de 2016
Ing. Rene Alfonso Carrillo Flores M.Sc.
CI: 1709140378
iv
CERTIFICACIÓN DE REVISORES
v
CALIFICACIONES
vi
CONTENIDO
DEDICATORIA ....................................................................................................................... ii
AUTORIZACIÓN DE LA AUTORÍA INTELECTUAL ..............................................................iii
CERTIFICACIÓN DEL TUTOR ............................................................................................. iv
CERTIFICACIÓN DE REVISORES ....................................................................................... v
CALIFICACIONES ................................................................................................................. vi
LISTA DE ANEXOS ................................................................................................................ x
LISTA DE FIGURAS.............................................................................................................. xi
LISTA DE TABLAS ............................................................................................................... xiii
RESUMEN ............................................................................................................................xiv
ABSTRACT........................................................................................................................... xv
INTRODUCCIÓN .................................................................................................................... 1
1.
MARCO TEÓRICO .................................................................................................. 3
1.1
Ruby on Rails ........................................................................................................... 3
1.1.1
Ruby ......................................................................................................................... 3
1.1.2
Rails ......................................................................................................................... 3
1.1.3
Ruby gem ................................................................................................................. 4
1.2
Arquitectura MVC ..................................................................................................... 4
1.2.1
Modelo...................................................................................................................... 5
a)
Active Record ........................................................................................................... 5
b)
Migraciones .............................................................................................................. 7
c)
Validaciones ............................................................................................................. 9
d)
Callback ................................................................................................................. 15
e)
Asociaciones .......................................................................................................... 17
vii
1.2.2
View (Vistas) .......................................................................................................... 24
1.2.3
Controlador (Controller) ......................................................................................... 31
2.
METODOLOGÍA DE DESARROLLO .................................................................... 37
2.1
Tipo de la Investigación ......................................................................................... 37
2.2
Población ............................................................................................................... 37
2.3
Método de Investigación ........................................................................................ 38
3.
CALCULOS Y RESULTADOS .............................................................................. 39
3.1
Paquete de Instalación .......................................................................................... 39
3.2
Instalación y configuración .................................................................................... 39
3.3
Mi primera aplicación ............................................................................................. 41
3.3.1
Creación de los recursos ....................................................................................... 41
3.3.2
Poner en marcha el servidor Web ......................................................................... 43
3.3.3
Hola, Rails .............................................................................................................. 45
3.4
Aplicación web completa ....................................................................................... 47
3.4.1
Creación de Modelos ............................................................................................. 49
3.4.2
Modelo uno a muchos ........................................................................................... 51
3.4.3
Modelo muchos a muchos ..................................................................................... 52
3.4.4
Actualizar o crear campos ..................................................................................... 53
3.4.5
Crear Campos para archivos ................................................................................. 55
3.4.6
Manejo de Vistas ................................................................................................... 58
3.4.7
Assets..................................................................................................................... 63
3.4.8
Validaciones ........................................................................................................... 65
3.4.9
Buscador y paginación .......................................................................................... 66
3.4.10
Autenticación de usuario ....................................................................................... 68
4.
DISCUSIÓN ........................................................................................................... 74
viii
5.
CONCLUSIONES .................................................................................................. 79
6.
RECOMENDACIONES .......................................................................................... 81
BIBLIOGRAFÍA ..................................................................................................................... 83
ANEXOS ............................................................................................................................... 85
ix
LISTA DE ANEXOS
ANEXO A
Device ................................................................................................................................87
ANEXO B
Cargar aplicación al servidor ............................................................................................89
ANEXO C
Configurar Correo Electrónico ..........................................................................................90
ANEXO D
Carrito Básico de Compras ...............................................................................................92
ANEXO E
Diagrama de Flujo ...........................................................................................................104
x
LISTA DE FIGURAS
Figura 1. Asociación belong_to (Dev & Noria, s.f.) .............................................................. 19
Figura 2. Asociación has_one (Dev & Noria, s.f.) ................................................................ 19
Figura 3. Asociación has_many (Dev & Noria, s.f.) ............................................................. 20
Figura 4. Asociación has_many :through (Dev & Noria, s.f.) .............................................. 20
Figura 5. Asociación has_one :through (Dev & Noria, s.f.) ................................................. 21
Figura 6. Asociación has_and_belongs_to_many (Dev & Noria, s.f.) ................................. 22
Figura 7. Asociaciones polimórficas (Dev & Noria, s.f.) ...................................................... 23
Figura 8. Ventana de instalación de Ruby/Rails .................................................................. 39
Figura 9. Ventana para seleccionar la ubicación ................................................................. 40
Figura 10. Directorio AppWeb .............................................................................................. 42
Figura 11. WEBrick ............................................................................................................... 44
Figura 12 Hola Rails! ............................................................................................................ 46
Figura 13. Modelo Entidad Relación .................................................................................... 49
Figura 14. Vista Tipos de Productos .................................................................................... 50
Figura 15. Vista de Fabricante ............................................................................................. 50
Figura 16. Vista Producto ..................................................................................................... 51
Figura 17. Vista Proveedor................................................................................................... 52
Figura 18. ImageMagick ....................................................................................................... 55
Figura 19. ImageMagick Tasks ............................................................................................ 55
Figura 20. Vista Fabricante Editada ..................................................................................... 58
Figura 21. Vista Fabricante Show ........................................................................................ 59
Figura 22. Vista Fabricante Index ........................................................................................ 59
Figura 23. Vista Producto Editada ....................................................................................... 61
Figura 24. Vista Producto Show........................................................................................... 62
Figura 25. Vista Producto Index ........................................................................................... 63
Figura 26. Menu de Navegación .......................................................................................... 65
Figura 27. Buscador ............................................................................................................. 68
Figura 28. Inicio de Sesión ................................................................................................... 70
Figura 29. Autenticación ....................................................................................................... 71
Figura 30. Aplicación aplicado estilos .................................................................................. 73
Figura 31 Producto Home .................................................................................................... 92
Figura 32 Añadir Carrito ....................................................................................................... 96
Figura 33 Mis compras ....................................................................................................... 102
Figura 34 Super Usuario .................................................................................................... 104
Figura 35 Un diagrama de flujo a nivel de contexto .......................................................... 105
xii
LISTA DE TABLAS
Tabla 1. Rutas de recursos (Dev & Noria, s.f.) .................................................................... 35
Tabla 2. Archivos y Carpetas creadas ................................................................................. 43
xiii
RESUMEN
ANÁLISIS DESCRIPTIVO DE LA TECNOLOGÍA RUBY ON RAILS PARA EL
DESARROLLO DE PÁGINAS WEB
Autor: Alex Fernando Pico Coba
Tutor: René Alfonso Carrillo Flores
El presente proyecto es una guía para el desarrollo de aplicaciones web utilizando la
tecnología Ruby on Rails, describe paso a paso con un ejemplo y presenta información de
esta herramienta para el uso e inducción al desarrollo de aplicaciones web. Es uno de los
primeros trabajos en el Ecuador que recolecta elementos básicos para la introducción al
desarrollo de aplicaciones web utilizando Ruby on Rails.
PALABRAS CLAVES: / LENGUAJE RUBY/ FRAMEWORK RAILS/ ACTIVE RECORD/
CONVENCIÓN SOBRE CONFIGURACIÓN / APLICACIÓN WEB / ARQUITECTURA MVC
xiv
ABSTRACT
DESCRIPTIVE ANALYSIS OF RUBY ON RAILS TECHNOLOGY FOR WEB PAGES
DEVELOPMENT
Autor: Alex Fernando Pico Coba
Tutor: René Alfonso Carrillo Flores
This project is a guide to develop web applications using Ruby on Rails technology, it
describes step by step with an example and present an information of this tool in order to
use and induction to web application development. It is one of the first works in Ecuador
that collect basic elements for introduction to web aplication development using Ruby on
Rails.
KEYWORDS: / RUBY LANGUAGE / RAILS FRAMEWORK / ACTIVE RECORD /
CONVENTION OVER CONFIGURATION / WEB APPLICATION / MVC ARCHITECTURE
I CERTIFY that the above and foregoing is a true and correct translation of the original
document in Spanish.
Lcdo. Diego Mauricio Manotoa Toapanta
Certified Translator
ID: 1710738483 (1005-14-1279868 SENESCYT)
xv
INTRODUCCIÓN
“Uno de los primeros lenguajes de programación para el desarrollo de aplicaciones web
es Perl1, el mismo que apareció antes de que internet fuera de fácil accesibilidad al
público en general, posteriormente en 1995 el programador Rasmus Lerdorf puso a
disposición el lenguaje PHP con lo que el desarrollo de aplicaciones web despegó. Hoy en
día, incluso muchas de estas aplicaciones se han desarrollado en PHP, como Google,
Facebook y Wikipedia” (BARZANALLA, 2012). En la actualidad existen un gran número
de lenguajes de aplicaciones web, siendo parte de estos Ruby con su framework Rails.
Bajo este lenguaje se han desarrollado aplicaciones como: Twitter en su inicio, Hulu
propiedad de NBC, FOX y Disney para crear su plataforma de distribución audiovisual
digital, Bloomberg una de las mayores corporaciones del mundo dedicada a las finanzas,
twitch una de las plataformas de video especializada en el streaming en directo de
partidas de videojuegos, entre otras aplicaciones.
Ruby on Rails es un entorno de desarrollo web de código abierto que está optimizado
para satisfacción de los programadores y de la productividad. Permite escribir un buen
código favoreciendo la convención antes que la configuración. Además de construir
aplicaciones web flexibles y robustas rápidamente. Las dos piezas principales de este
entorno son dos: Ruby, es un lenguaje de programación enfocado a la simplicidad y a la
productividad, con una sintaxis elegante y natural. Es un lenguaje de script totalmente
orientado a objetos. La segunda pieza principal es Rails, este es un framework creado
para el desarrollo de aplicaciones web, para entender mejor, es una serie de utilidades y
herramientas para crear aplicaciones web más rápidamente que haciéndolo desde cero.
“Ruby on Rails fue escrito por David Heinemeier Hansson a partir de su trabajo en
Basecamp. Fue liberado al público por primera vez en julio de 2004” (HEINEMEIER,
2006).
1
Inventado por Larry Wall en 1987
1
Al momento de escoger una herramienta para el desarrollo de aplicaciones web se inicia
por la búsqueda de material didáctico, guie el desarrollo de la aplicación y contar con un
tutorial completo que permita los primeros pasos en el desarrollo de alguna aplicación en
particular.
Actualmente en el Ecuador no se cuenta con un documento que cumpla lo descrito en el
párrafo anterior por lo que el objetivo principal es; describir analíticamente el desarrollo
completo de una aplicación web, utilizando el lenguaje de programación Ruby y el
framework exclusivo Rails.
Las aplicaciones web brindan servicios importantes entre ellas el acceso a la información,
disminuye costos, tiempos y aumenta la accesibilidad a la información desde cualquier
parte del mundo.
Existen varios lenguajes y herramientas para el desarrollo de aplicaciones web, tanto
propietario como gratuito. Para un cierto grupo de la población que quiera inducirse en el
mundo del desarrollo de aplicaciones web resulta costoso la adquisición licencias o
herramientas, por lo que muy probablemente buscará variantes gratuitas a fin de
satisfacer su necesidad de empezar en el desarrollo de aplicaciones.
Ruby on Rails es una herramienta gratuita que permite el desarrollo de aplicaciones web
orientada a objetos, se ha diseñado para que sea fácil de leer y escribir, no solo gratis
sino libre para usarlo, copiarlo, modificarlo y distribuirlo.
La información que existe acerca de Ruby on Rails se encuentra dispersa y no es capaz
de influir en la población para el uso de esta herramienta, sabiendo además que no hay
aplicaciones difundidas desarrolladas con Ruby on Rails en el Ecuador, éste estudio es el
primer trabajo investigativo sobre esta tecnología que ayudará a la comunidad a
acercarse más al lenguaje y tener una fuente de investigación que facilite el desarrollo de
las primeras aplicaciones web.
2
1. MARCO TEÓRICO
1.1
1.1.1
Ruby on Rails
Ruby
Es un lenguaje de programación enfocado a la simplicidad y a la productividad, con una
sintaxis elegante y natural, que le hace muy fácil de entender. Es un lenguaje de script (no
compilado), totalmente orientado a objetos, aquí todo es un objeto y por tanto se le
pueden asociar propiedades y métodos, así como redefinir o extender su comportamiento.
Desde su liberación pública en 1995, Ruby ha atraído devotos desarrolladores de
todo el mundo. En el 2006, Ruby alcanzó reconocimiento masivo, formándose
grupos de usuarios activos en las ciudades más importantes del mundo y llenando
las capacidades de las conferencias relacionadas a Ruby.
El índice TIOBE, que mide el crecimiento de los lenguajes de programación, ubica
a Ruby en la posición #13 del ranking mundial. Refiriéndose a su crecimiento,
predicen, “Todo indica que Ruby llegará a estar entre los primeros”. (RUBY, s.f.)
1.1.2
Rails
Ruby on Rails, también conocido como RoR o Rails, es un framework de aplicaciones
web de código abierto escrito en el lenguaje de programación Ruby, siguiendo el
paradigma de la arquitectura Modelo Vista Controlador (MVC). “Trata de combinar la
simplicidad con la posibilidad de desarrollar aplicaciones del mundo real escribiendo
menos código que con otros frameworks y con un mínimo de configuración. El lenguaje de
programación Ruby permite la metaprogramación, de la cual Rails hace uso, lo que
resulta en una sintaxis que muchos de sus usuarios encuentran muy legible” (WIKIPEDIA,
Ruby on Rails, 2016).
La filosofía Rails incluye dos grandes principios:
3

Don't Repeat Yourself: como lo dicen en (WIKIPEDIA, Ruby on Rails, 2016) se lo
conoce como DRY, es un principio de desarrollo de software que establece que
"Cada pieza de conocimiento debe tener una única representación autorizada, sin
ambigüedades, dentro de un sistema." Para no escribir la misma información una y
otra vez.

Convention Over Configuration: como dice en (WIKIPEDIA, Ruby on Rails,
2016) Rails tiene opiniones sobre la mejor manera de hacer muchas cosas en una
aplicación
web, y
los
valores
predeterminados
para
este
conjunto
de
convenciones, antes que se requiera que se especifique cada detalle a través de
archivos de configuración sin fin.
1.1.3
Ruby gem
Una gema es, básicamente, la manera en que Ruby permite distribuir programas,
módulos o librerías que extienden funcionalidad, casi siempre específica, volviendo más
fácil el flujo de desarrollo. Por ejemplo, hay gemas para Rails que se encargan de la
autenticación de usuarios como es el caso de Devise. Para casi cada acción que se
realiza repetitivamente a la hora de programar, existe una gema que lo vuelve todo más
fácil. Cabe decir que las gemas pueden depender de otras gemas para funcionar.
Rails es la gema más famosa de Ruby, muchas personas llegan a Rails sin saber
Ruby y después se dan cuenta que deben conocer la sintaxis básica del lenguaje
para aprender a utilizar la herramienta (PUENTE, 2014).
1.2
Arquitectura MVC
El modelo vista controlador (MVC) según (BURBECK, 2015) es un patrón de arquitectura
de software que separa los datos y la lógica de negocio de una aplicación de la interfaz de
usuario y el módulo encargado de gestionar los eventos y las comunicaciones. Para ello
MVC propone la construcción de tres componentes distintos que son el modelo, la vista y
el controlador, es decir, por un lado define componentes para la representación de la
información, y por otro lado para la interacción del usuario. Este patrón de arquitectura de
software se basa en las ideas de reutilización de código y la separación de conceptos.
4
1.2.1
Modelo
a) Active Record
Es la capa del sistema, responsable de representar los datos del negocio y la lógica.
Active Record facilita la creación y el uso de objetos del negocio, cuyos datos
requieren un almacenamiento en una base de datos. (DEV & Noria, s.f.)
Object-Relational Mapping.- Comúnmente conocida como su abreviatura ORM, según
(DEV & Noria, s.f.) es una técnica que conecta los objetos de una aplicación a las tablas
en una base de datos relacional. Usando ORM, las propiedades y relaciones de los
objetos en una aplicación se pueden almacenar y recuperar fácilmente de una base de
datos, sin tener que escribir sentencias SQL y con menos código de acceso a la base de
datos.
Active Record da varios mecanismos, siendo los más importantes:

Representar modelos y sus datos.

Representar asociaciones entre los modelos.

Representar jerarquías de herencia a través de modelos relacionados.

Validar los modelos antes de que se conservan en la base de datos.

Realizar operaciones de base de datos de una forma orientada a objetos.
Active Record usa algunas convenciones de nombres para averiguar cómo se debe
crear la correlación entre los modelos y tablas de la base de datos. Rails pluraliza sus
nombres de clase para encontrar la tabla de la base de datos respectiva. Así, para una
clase Book, se debe tener una tabla en la base de datos llamada books. En Rails los
mecanismos de pluralización son muy potentes, siendo capaces de pluralizar (y
singularizar) palabras regulares e irregulares. Al utilizar nombres de clases
compuestas de dos o más palabras, el nombre de la clase modelo debe seguir las
convenciones de Ruby, usando el formulario de CamelCase, mientras que el nombre
de la tabla debe contener las palabras separadas por guiones. (DEV & Noria, s.f.)
Hay algunos nombres de columnas opcionales que añaden funciones adicionales para
casos de Active Record, según (DEV & Noria, s.f.):
5

created_at: Automáticamente se establece con la fecha y hora actuales cuando se
creó por primera vez el registro.

updated_at: Automáticamente se establece con la fecha y hora actuales cada vez
que se actualiza el registro.

lock_version: Añade un bloqueo optimistic a un modelo.

type: Especifica que el modelo utiliza herencias de tablas individuales.

(association_name)_type: Almacena el tipo de asociaciones polimórficas.

(table_name)_count: Se utiliza para almacenar en caché el número que
pertenece a los objetos sobre las asociaciones. Por ejemplo, una columna
comments_count en una clase Articles que tiene muchos casos de comentarios
en caché, es decir el número de comentarios existentes para cada artículo.
CRUD: lectura y escritura de datos
CRUD es un acrónimo de cuatro verbos que se utiliza para operar los datos: C
reate,
R ead, U pdate y D elete, Active Record crea automáticamente métodos
para permitir a una aplicación leer y manipular los datos almacenados dentro de
sus tablas. (DEV & Noria, s.f.)
Create (Crear).- Los objetos de Active Record pueden ser creados a partir de un
hash o un bloque. El
método new devolverá un nuevo objeto, mientras que
create devolverá el objeto y lo guarda en la base de datos. (DEV & Noria, s.f.)
Por ejemplo, dado un modelo de User con atributos de name y occupation, llamando
al método create va a crear y guardar un nuevo registró en la base de datos:
user = User.create(name: "David", occupation: "Code Artist")
Read (Leer).- Active Record proporciona una API para acceder a datos dentro de una
base de datos. A continuación se presentan algunos ejemplos de diferentes métodos de
acceso a datos, proporcionados por Active Record.
# Devuelve una colección con todos los usuarios
users = User.all
# Devolver el primer usuario
user = User.first
# Devuelve el primer usuario llamado David
6
david = User.find_by(name: 'David')
# Encuentra todos los usuarios llamados David, que son Code
Artists y ordenar por created_at en orden cronológico inverso
users = User.where(name: 'David', occupation: 'Code
Artist').order(created_at: :desc)
Update (actualizar).- Una vez que un objeto Active Record se ha recuperado, sus
atributos pueden ser modificados y que se pueden guardar en la base de datos.
user = User.find_by(name: 'David')
user.name = 'Dave'
user.save
La abreviatura de esto es utilizar una asignación de nombres de atributos de hash al valor
deseado, así:
user = User.find_by(name: 'David')
user.update(name: 'Dave')
Esto es muy útil cuando se actualiza varios atributos a la vez. Si, por el contrario, desea
actualizar varios registros, se puede usar el método de la clase update_all así:
User.update_all "max_login_attempts = 3, must_change_password =
'true'"
Delete (Borrar).- Así mismo, una vez recuperado un objeto de Active Record puede ser
destruido, el cual se elimina de la base de datos.
user = User.find_by(name: 'David')
user.destroy
b) Migraciones
Las migraciones son una forma conveniente para modificar el esquema de la base de
datos a través del tiempo, de una manera consistente y fácil. Estos utilizan una
conexión DSL de Ruby de modo que no tiene que escribir SQL a mano, permitiendo
que su esquema y los cambios de la base de datos sean independientes. (DEV &
Noria, s.f.)
Se puede pensar en cada migración como una nueva versión de la base de datos. Un
esquema comienza vacío, y cada migración lo modifica para agregar o quitar tablas,
7
columnas o entradas. Active Record sabe cómo actualizar el esquema a lo largo de esta
línea de tiempo, llevándolo desde cualquier punto que esté hacia la última versión. Active
Record también actualizará su archivo db/schema.rb
para que coincida con la
estructura hasta la fecha de la base de datos.
Los generadores de modelo y generadores de Scaffold crearán migraciones apropiadas
para la creación de un nuevo modelo. Esta migración ya contendrá instrucciones para la
creación de la tabla correspondiente. Si se le dice a Rails las columnas que se desea,
entonces las declaraciones de estas columnas también se crean.
Las migraciones se almacenan como archivos en el directorio db/migrate, uno para
cada
clase
de
migración.
El
nombre
del
archivo
es
de
la
forma
YYYYMMDDHHMMSS_create_products.rb.
class CreateProducts < ActiveRecord::Migration
def change
create_table :products do |t|
t.string :name
t.text :description
t.timestamps null: false
end
end
end
Esta migración crea un método llamado change que se usará cuando se ejecuta
esta migración. La acción que define este método también es reversible, lo que
significa que Rails sabe cómo revertir el cambio realizado por esta migración, en
caso de que se desee invertir en cualquier momento. Además agrega una tabla
denominada products con una columna name y una columna description.
Una columna con la clave principal de nombre ID también se añadirá de forma
implícita, ya que es la clave principal por defecto para todos los modelos Active
Record. El macro timestamps
añade dos columnas, created_at y
updated_at. Estas columnas especiales son administradas automáticamente por
Active Record. (DEV & Noria, s.f.)
8
c) Validaciones
Las validaciones se utilizan para garantizar que sólo los datos válidos se guarden en
la base de datos. Por ejemplo, puede ser importante para su aplicación asegurarse de
que cada usuario proporciona una dirección de correo electrónico válida. Las
validaciones a nivel de modelo son la mejor manera de garantizar que sólo los datos
válidos se guarden en la base de datos. Rails hace que sean fáciles de usar, y
también le permite crear sus propios métodos de validación. (DEV & Noria, s.f.)
¿Cuándo ocurren las validaciones?
Hay dos tipos de objetos de Active Record: las que corresponden a una fila dentro de su
base de datos y aquellos que no lo hacen. Cuando se crea un objeto nuevo, por ejemplo,
utilizando el método new, ese objeto no pertenece a la base de datos todavía. Una vez
que llame al método save, el objeto se guardará en la tabla de la base de datos
adecuada. Active Record utiliza el método de instancia new_record para determinar si
un objeto ya está en la base de datos o no lo está. Considere la siguiente clase Active
Record simple:
class Person < ActiveRecord::Base
end
Se puede ver cómo funciona examinado algunos salidas de la consola de rails:
$ bin/rails console
>> p = Person.new(name: "John Doe")
=> #<Person id: nil, name: "John Doe", created_at: nil,
updated_at: nil>
>> p.new_record?
=> true
>> p.save
=> true
>> p.new_record?
=> false
La creación y almacenamiento de un nuevo registro enviará una operación de
SQL INSERT a la base de datos. La actualización de un registro existente enviará una
operación de SQL UPDATE. Las validaciones se suelen ejecutar antes de que estos
comandos se envíen a la base de datos. Si algunas validaciones fallan, el objeto se marca
como no válido y Active Record no llevará a cabo la operación INSERT o UPDATE. Esto
9
evita el almacenamiento de un objeto no válido en la base de datos. Se puede optar por
tener validaciones específicas que se ejecutan cuando se crea un objeto, guarda o
actualiza.
Los siguientes métodos desencadenan validaciones, y se guardará el objeto en la base de
datos sólo si el objeto es válido: create, create!, save, save!, update,
update!
Tenga en cuenta que guardar también tiene la capacidad de saltar validaciones si se
aprueba validate:false
como
argumento. Esta
técnica
se
debe
utilizar
con
precaución.
save(validate: false)
Métodos de validación
Active Record ofrece muchos métodos de validación predefinidas que se pueden utilizar
directamente dentro de sus definiciones de clase. Estos métodos proporcionan reglas de
validación comunes. Cada vez que falla la validación, se añade un mensaje de error a la
colección de errores de los objetos, y este mensaje está asociado con el atributo a ser
validado.
Cada método acepta un número arbitrario de nombres de atributos, así que con una sola
línea de código se puede agregar el mismo tipo de validación a varios atributos.
Acceptance.- Este método valida que una casilla de verificación (checkbox) en la
interfaz de usuario se ha aceptado cuando se envía un formulario. Esto se usa
típicamente cuando el usuario tiene que estar de acuerdo con los términos de su
aplicación de servicio, confirme la lectura de un texto, o cualquier concepto similar. Esta
validación es muy específica para aplicaciones web y esta "validación" no tiene que ser
guardada en su base de datos (si no tiene un campo para ello, este método crea un
atributo virtual).
class Person < ActiveRecord::Base
validates :terms_of_service, acceptance: true
end
10
Validates_associated.- Debe utilizar este método cuando el modelo tiene asociaciones
con otros modelos y que también necesita ser validado. Cuando intenta guardar su
objeto, valid? será llamado a cada uno de los objetos asociados.
class Library < ActiveRecord::Base
has_many :books
validates_associated :books
end
Confirmation.- Debe utilizar este método cuando se tiene dos campos de texto que
deben tener exactamente el mismo contenido. Por ejemplo, es posible que desee
confirmar una dirección de correo electrónico o una contraseña. Esta validación crea un
atributo virtual cuyo nombre es el nombre del campo que tiene que ser confirmado con
"_confirmation" adjuntado.
class Person < ActiveRecord::Base
validates :email, confirmation: true
end
En su plantilla de vista se podría utilizar algo como:
<%= text_field :person, :email %>
<%= text_field :person, :email_confirmation %>
Exclusion.- Este método valida que los valores de los atributos no estén incluidos en un
conjunto dado. De hecho, este conjunto puede ser cualquier objeto numerable.
class Account < ActiveRecord::Base
validates :subdomain, exclusion: { in: %w(www us ca jp),
message: "%{value} is reserved." }
end
Format.- Este método valida los valores de los atributos probando si coinciden con una
expresión regular dada, que se especifica mediante la opción :with.
class Product < ActiveRecord::Base
validates :legacy_code, format: { with: /\A[a-zA-Z]+\z/,
message: "only allows letters" }
end
Alternativamente, se puede requerir que el atributo especificado no coincida con la
expresión regular mediante el uso de la opción :without.
11
Inclusion.- Este método valida que los valores de los atributos se incluyen en un conjunto
dado. De hecho, este conjunto puede ser cualquier objeto numerable.
class Coffee < ActiveRecord::Base
validates :size, inclusion: { in: %w(small medium large),
message: "%{value} is not a valid size" }
end
Length.- Este método valida la longitud de los valores de los atributos. Se ofrece una
variedad de opciones, por lo que puede especificar restricciones de longitud de diferentes
maneras:
class Person < ActiveRecord::Base
validates :name, length: { minimum: 2 }
validates :bio, length: { maximum: 500 }
validates :password, length: { in: 6..20 }
validates :registration_number, length: { is: 6 }
end
Las posibles opciones de length de restricción son:

:minimum - El atributo no puede tener menos de la longitud especificada.

:maximum - El atributo no puede tener más de la longitud especificada.

:in (o :within) - La longitud del atributo debe ser incluido en un intervalo
dado. El valor de esta opción debe tener un intervalo.

:is - La longitud del atributo debe ser igual al valor dado.
Numericality.- Este método valida que sus atributos sólo tienen valores numéricos. De
forma predeterminada, se separa con un signo opcional seguido de un número de coma
flotante o integral. Para especificar que sólo permite
los números enteros se puede
especificar :only_integer como verdadero.
Si establece :only_integer como verdadero , entonces se usará la expresión regular
/\A[+-]?\d+\Z/ para validar el valor del atributo. De lo contrario, tratará de convertir el
valor a un número Float.
class Player < ActiveRecord::Base
validates :points, numericality: true
validates :games_played, numericality: { only_integer: true }
end
12
Además :only_integer , también acepta las siguientes opciones para añadir
restricciones a los valores aceptados:

:greater_than - Especifica que el valor debe ser mayor que el valor
suministrado.

:greater_than_or_equal_to - Especifica que el valor debe ser mayor o igual
que el valor suministrado.

:equal_to - Especifica que el valor debe ser igual al valor suministrado.

:less_than - Especifica que el valor debe ser menor que el valor suministrado.

:less_than_or_equal_to - Especifica que el valor debe ser menor o igual al
valor suministrado.

:odd - Especifica que el valor debe ser un número impar

:even - Especifica que el valor debe ser un número par si es true.
Presence.- Este método valida que los atributos especificados no están vacíos. Se utiliza
el método blank? para comprobar si el valor es nulo o una cadena en blanco, es decir,
una cadena que está vacía o consiste en un espacio en blanco.
class Person < ActiveRecord::Base
validates :name, :login, :email, presence: true
end
Absence.- Este método valida que los atributos especificados estén ausentes. Utiliza
el método present? para comprobar si el valor no es nulo o bien una cadena en blanco,
es decir, una cadena que está vacía o consiste en un espacio en blanco.
class Person < ActiveRecord::Base
validates :name, :login, :email, absence: true
end
Uniqueness.- Este método valida que el valor del atributo sea único, justo antes de que el
objeto se guarde. No crea una restricción de unicidad en la base de datos, por lo que
puede suceder que dos conexiones de bases de datos diferentes crean dos registros con
el mismo valor para una columna que tiene la intención de ser único. Para evitar esto, se
debe crear un índice único en ambas columnas en su base de datos.
13
class Account < ActiveRecord::Base
validates :email, uniqueness: true
end
La validación ocurre mediante la realización de una consulta SQL en la tabla del modelo,
la búsqueda de un registro existente con el mismo valor en ese atributo.
Opciones de validación comunes
:allow_nil.- La opcion :allow_nil se salta la validación cuando el valor que se está
validando es nula o vacía.
class Coffee < ActiveRecord::Base
validates :size, inclusion: { in: %w(small medium large),
message: "%{value} is not a valid size" }, allow_nil: true
end
:allow_blank.- La opción :allow_blank es similar a la opción :allow_nil . Esta
opción le permitirá pasar la validación si el valor del atributo es blank?, como nulo o una
cadena vacía, por ejemplo:
class Topic < ActiveRecord::Base
validates :title, length: { is: 5 }, allow_blank: true
end
Topic.create(title: "").valid? # => true
Topic.create(title: nil).valid? # => true
:message.- Como ya se ha visto, la opción :message le permite especificar el mensaje
que se añadirá a la colección de errores cuando la validación falla. Cuando no se utiliza
esta opción, Active Record utilizará el mensaje de error predeterminado respectivo para
cada método de validación.
:on.- La opción :on le permite especificar cuando la validación debería suceder. El
comportamiento por defecto para todos los métodos de validación incorporadas se va a
ejecutar cuando se guarde (cuando se va a crear un nuevo registro y cuando se está
actualizando). Si desea cambiarlo, puede utilizar on:
:create para ejecutar la
validación sólo cuando se crea un nuevo registro o on: :update para ejecutar la
validación sólo cuando se actualiza un registro.
14
class Person < ActiveRecord::Base
validates :email, uniqueness: true, on: :create
validates :age, numericality: true, on: :update
validates :name, presence: true
end
d) Callback
Durante el funcionamiento normal de una aplicación Rails, los objetos se pueden
crear, actualizar, y destruir. Active Record ofrece hooks en este ciclo de vida del
objeto para que pueda controlar su aplicación y sus datos. Callbacks le permiten
desencadenar la lógica antes o después de una alteración del estado de un objeto.
(DEV & Noria, s.f.)
Visión general sobre Callbacks.- Callbacks son métodos que serán llamadas en ciertos
momentos del ciclo de vida de un objeto. Con los Callback es posible escribir código que
se ejecutará cada vez que se crea un objeto Active Record, crear, actualizar, eliminar,
validar, o cargar desde la base de datos.
Registro
Callback.-
Para
utilizar
los
Callbacks
disponibles,
es
necesario
registrarlos. Puede implementar los Callbacks como métodos ordinarios y utilizar un
método de clase de estilo macro para registrarlos como Callback:
class User < ActiveRecord::Base
validates :login, :email, presence: true
before_validation :ensure_login_has_a_value
protected
def ensure_login_has_a_value
if login.nil?
self.login = email unless email.blank?
end
end
end
Los Callbacks también pueden ser registrados sólo en determinados eventos del ciclo de
vida:
class User < ActiveRecord::Base
before_validation :normalize_name, on: :create
after_validation :set_location, on: [ :create, :update ]
protected
15
def normalize_name
self.name = self.name.downcase.titleize
end
def set_location
self.location = LocationService.query(self)
end
end
Se considera una buena práctica para declarar métodos de Callbacks como protegido o
privado. Si se deja pública, se pueden llamar desde fuera del modelo y violan el principio
de encapsulación del objeto.
Clases de callback
A veces los métodos de callback que se escribe son lo suficientemente útiles para ser
reutilizados por otros modelos. Active Record hace posible la creación de clases que
encapsulan los métodos de callback, lo que hace muy fácil de volver a utilizarlos.
He aquí un ejemplo en el que se crea una clase con un callback after_destroy para
un modelo PictureFile :
class PictureFileCallbacks
def after_destroy(picture_file)
if File.exist?(picture_file.filepath)
File.delete(picture_file.filepath)
end
end
end
Cuando se declara dentro de una clase, los métodos de Callbacks recibirán el modelo de
objeto como parámetro. Ahora puede utilizar la clase Callbacks en el modelo:
class PictureFile < ActiveRecord::Base
after_destroy PictureFileCallbacks.new
end
Tenga en cuenta que se tiene que crear una instancia de un nuevo objeto
PictureFileCallbacks, ya que la Callbacks está declarada como un método de
instancia. Esto es particularmente útil si los Callbacks hacen uso del estado del objeto
instanciado. A menudo, sin embargo, tendrá más sentido declarar los Callbacks como
métodos de clase:
16
class PictureFileCallbacks
def self.after_destroy(picture_file)
if File.exist?(picture_file.filepath)
File.delete(picture_file.filepath)
end
end
end
Si el método de Callbacks se declara de esta manera, no será necesario crear una
instancia de objeto PictureFileCallbacks .
class PictureFile < ActiveRecord::Base
after_destroy PictureFileCallbacks
end
Se puede declarar muchos Callbacks que desee dentro de las clases Callbacks.
e) Asociaciones
¿Por qué se necesita las asociaciones entre los modelos?, (DEV & Noria, s.f.) afirman,
que hacen las operaciones comunes más simples y fácil en el código. Por ejemplo,
considere una aplicación de simples guías que forman un modelo para los clientes y un
modelo para los pedidos. Cada cliente puede tener muchos pedidos. Sin asociaciones, las
declaraciones modelo se vería así:
class Customer < ActiveRecord::Base
end
class Order < ActiveRecord::Base
end
Ahora, suponga que desee añadir un nuevo pedido de un cliente existente. Entonces de
debe hacer algo como esto:
@order = Order.create(order_date: Time.now, customer_id:
@customer.id)
O considerar la eliminación de un cliente, y asegurar que todas sus órdenes se eliminan:
@orders = Order.where(customer_id: @customer.id)
@orders.each do |order|
order.destroy
end
@customer.destroy
17
Con las asociaciones de Active Record, puede simplificar esto y otras operaciones
diciéndole de forma declarativa a Rails que hay una conexión entre los dos modelos. Aquí
está el código para la creación de clientes y pedidos:
class Customer < ActiveRecord::Base
has_many :orders, dependent: :destroy
end
class Order < ActiveRecord::Base
belongs_to :customer
end
Con este cambio, la creación de un nuevo pedido para un cliente en particular es fácil:
@order = @customer.orders.create(order_date: Time.now)
La eliminación de un cliente y todos sus pedidos es mucho más fácil:
@customer.destroy.
Tipos de Asociaciones
En Rails, una asociación es una conexión entre dos modelos de Active Record. Las
asociaciones se implementan mediante llamadas de tipo macro, para que de forma
declarativa pueda agregar características a sus modelos. Por ejemplo, al declarar en un
modelo belongs_to a otro modelo, se indica a Rails que mantenga la información de la
clave primaria Key-Foreign entre instancias de los dos modelos, y también se obtiene una
serie de métodos de utilidad añadido a su modelo. Rails admite seis tipos de
asociaciones:
belongs_to,
has_one,
has_many,
has_many
:through,
has_one :through, has_and_belongs_to_many.
Asociación belongs_to.- Una asociación belongs_to establece una conexión uno-auno con otro modelo, de manera que cada instancia del modelo que se declara "pertenece
a" una instancia del otro modelo. Por ejemplo, si su aplicación incluye clientes y pedidos, y
cada orden puede ser asignado a un solo cliente, se declara el modelo de esta manera:
class Order < ActiveRecord::Base
belongs_to :customer
end
18
Figura 1. Asociación belong_to (DEV & Noria, s.f.)
Asociación has_one.- Una asociación has_one también establece una conexión uno-auno con otro modelo, pero con una semántica diferente (y consecuencias). Esta
asociación indica que cada instancia de un modelo contiene o posee una instancia de otro
modelo. Por ejemplo, si cada proveedor en su aplicación tiene sólo una cuenta, se puede
declarar el modelo de proveedor de la siguiente manera:
class Supplier < ActiveRecord::Base
has_one :account
end
Figura 2. Asociación has_one (DEV & Noria, s.f.)
Asociación has_many.- Una asociación has_many indica una conexión de uno a
muchos con otro modelo. A menudo encontrará esta asociación y en el "otro lado" una
asociación belongs_to. Esta asociación indica que cada instancia del modelo tiene cero
o más instancias de otro modelo. Por ejemplo, en una aplicación que contiene clientes y
pedidos, el modelo cliente podría ser declarado como esto:
class Customer < ActiveRecord::Base
has_many :orders
end
19
El nombre del otro modelo está en plural cuando se declara una asociación has_many.
Figura 3. Asociación has_many (DEV & Noria, s.f.)
Asociación has_many :through.- Una asociación has_many:through es a menudo
utilizada para establecer una conexión de muchos a muchos con otro modelo. Esta
asociación indica que el modelo que se declara se puede emparejar con cero o más
instancias de otro modelo procediendo a través de un tercer modelo. Por ejemplo,
considere una práctica médica que los pacientes hacen citas para ver a los médicos. Las
declaraciones de asociación pertinentes podrían tener este aspecto:
class Physician < ActiveRecord::Base
has_many :appointments
has_many :patients, through: :appointments
end
class Appointment < ActiveRecord::Base
belongs_to :physician
belongs_to :patient
end
class Patient < ActiveRecord::Base
has_many :appointments
has_many :physicians, through: :appointments
end
Figura 4. Asociación has_many :through (DEV & Noria, s.f.)
20
Asociación has_one :through.- Una asociación has_one:through establece una
conexión uno-a-uno con otro modelo. Esta asociación indica que el modelo que se declara
se puede emparejar con una instancia de otro modelo procediendo a través de un tercer
modelo. Por ejemplo, si cada proveedor tiene una cuenta, y cada cuenta se asocia con
una historia de la cuenta, entonces el modelo de proveedor podría tener este aspecto:
class Supplier < ActiveRecord::Base
has_one :account
has_one :account_history, through: :account
end
class Account < ActiveRecord::Base
belongs_to :supplier
has_one :account_history
end
class AccountHistory < ActiveRecord::Base
belongs_to :account
end
Figura 5. Asociación has_one :through (DEV & Noria, s.f.)
Asociación has_and_belongs_to_many.- crea una conexión directa de muchos a
muchos con otro modelo, con ningún modelo intermedio. Por ejemplo, si su aplicación
incluye conjuntos y partes, con cada conjunto que tiene muchas partes y cada parte
apareciendo en muchos conjuntos, se podría declarar los modelos de esta manera:
class Assembly < ActiveRecord::Base
has_and_belongs_to_many :parts
end
21
class Part < ActiveRecord::Base
has_and_belongs_to_many :assemblies
end
Figura 6. Asociación has_and_belongs_to_many (DEV & Noria, s.f.)
Las asociaciones polimórficas
Un giro un poco más avanzado en las asociaciones es la asociación polimórfica. Con las
asociaciones polimórficas, un modelo puede pertenecer a más de un modelo, en una sola
asociación. Por ejemplo, es posible que tenga un modelo de imagen que pertenece tanto
a un modelo empleado o un modelo de producto. Así es como este podría ser declarado:
class Picture < ActiveRecord::Base
belongs_to :imageable, polymorphic: true
end
class Employee < ActiveRecord::Base
has_many :pictures, as: :imageable
end
class Product < ActiveRecord::Base
has_many :pictures, as: :imageable
end
Se puede pensar en una declaración polimórfica belongs_to como la creación de una
interfaz que cualquier otro modelo puede utilizar. A partir de una instancia del modelo
Empleado, puede recuperar una colección de imágenes: @employee.pictures, del
mismo modo, se puede recuperar @product.pictures .
22
Si se tiene una instancia del modelo imagen, se puede llegar a través de su
matriz @picture.imageable. Para que esto funcione, tiene que declarar tanto una
columna de clave externa y una columna del tipo en el modelo que declara la interfaz
polimórfica:
class CreatePictures < ActiveRecord::Migration
def change
create_table :pictures do |t|
t.string :name
t.integer :imageable_id
t.string :imageable_type
t.timestamps null: false
end
add_index :pictures, :imageable_id
end
end
Esta migración puede ser simplificada mediante el uso de la forma t.references:
class CreatePictures < ActiveRecord::Migration
def change
create_table :pictures do |t|
t.string :name
t.references :imageable, polymorphic: true, index: true
t.timestamps null: false
end
end
end
Figura 7. Asociaciones polimórficas (DEV & Noria, s.f.)
23
1.2.2
View (Vistas)
Los Action View y Action Controller son los dos componentes principales de Action
Pack. En Rails, las peticiones web son manejadas por Action Pack, que divide el
trabajo, en una parte del controlador (la realización de la lógica) y una parte de la
vista (presentación de una plantilla (template)). Por lo general, Action Controller se
ocupará de la comunicación con la base de datos y la realización de acciones
CRUD cuando sea necesario. Action View es entonces el responsable de la
compilación de la respuesta. (DEV & Noria, s.f.)
Las plantillas Action View se escriben utilizando Ruby embebido en etiquetas que se
mezclan con HTML. Para evitar llenar las plantillas con código repetitivo, una serie de
clases de métodos proporcionan un comportamiento común para las formas, las fechas y
las cadenas. También es fácil de añadir nuevos métodos para su aplicación a medida que
evoluciona.
Uso de Action View con Rails
Para cada controlador hay un directorio asociado en el directorio app/views que contiene
los archivos de plantillas que componen las vistas asociadas a ese controlador. Estos
archivos se utilizan para mostrar la vista del resultado de cada acción del controlador.
Se va a echar un vistazo a lo que Rails hace por defecto cuando se crea un nuevo recurso
utilizando el generador scaffold :
$ bin/rails generate scaffold article
[...]
invoke scaffold_controller
create
app/controllers/articles_controller.rb
invoke
erb
create
app/views/articles
create
app/views/articles/index.html.erb
create
app/views/articles/edit.html.erb
create
app/views/articles/show.html.erb
create
app/views/articles/new.html.erb
create
app/views/articles/_form.html.erb
[...]
Hay una convención de nomenclatura para las vistas en Rails. Por lo general, los puntos
de vista comparten su nombre con la acción del controlador asociado, como se puede ver
24
arriba. Por ejemplo, la acción index del controlador articles_controller.rb utilizará el
archivo de vista index.html.erb en el directorio app/views/articles. El HTML completo que
devuelve al cliente se compone de una combinación de este archivo ERB, una plantilla de
diseño (Layouts Templates) que lo envuelve, y todos los parciales (Partials) que la vista
puede hacer referencia.
Templates, Partials and Layouts
Como se ha mencionado, la salida HTML final es una composición de tres elementos
Rails: Templates, Partials y Layouts (plantillas, Parciales y Diseños). A continuación se
muestra una breve descripción de cada uno de ellos.
Plantillas (Templates)
Action View templates se pueden escribir de varias maneras. Si el archivo de
plantillas tiene una extensión .erb entonces se utiliza una mezcla de ERB (Ruby
Embebido) y HTML. Si el archivo de plantilla tiene una extensión .builder entonces se
utiliza la biblioteca Builder::XmlMarkup.
Rails soporta múltiples sistemas de plantillas y utiliza una extensión de archivo
para distinguirlos entre ellos. Por ejemplo, un archivo HTML que usa el sistema de
plantillas ERB tendrá .html.erb como extensión de archivo. (DEV & Noria, s.f.)
ERB.- Dentro de una plantilla de ERB, el código Ruby se puede incluir con el uso de las
etiquetas <% %> y <%= %>. Las etiquetas <% %> se utilizan para ejecutar código Ruby
que no devuelve nada, como las condiciones, bucles o bloques, y las etiquetas <%=
%> se utilizan cuando se requiere salida.
Considere el siguiente bucle de nombres:
<h1>Names of all the people</h1>
<% @people.each do |person| %>
Name: <%= person.name %><br>
<% end %>
El bucle se configura usando las etiquetas de incrustación regulares ( <% %> ) y se
inserta el nombre utilizando la salida de la incorporación de etiquetas ( <%=
%> ). Tenga en cuenta que esto no es sólo una sugerencia de uso: funciones de salida
25
regulares, tales como print y puts no se consideran en la vista con las plantillas ERB. Por
lo que esto sería un error:
<%# WRONG %>
Hi, Mr. <% puts "Frodo" %>
Para
suprimir
espacios
en
blanco
iniciales
y
finales,
puede
utilizar <%- -
%> intercambiable con <% y %>.
Constructor (Builder).- Plantillas del Constructor son una alternativa más programática
de ERB. Son especialmente útiles para la generación de contenido XML. Un objeto
XmlMarkup llamado xml se realiza automáticamente a disposición de plantillas con una
extensión .builder . Estos son algunos ejemplos básicos:
xml.em("emphasized")
xml.em { xml.b("emph & bold") }
xml.a("A Link", "href" => "http://rubyonrails.org")
xml.target("name" => "compile", "option" => "fast")
lo que produciría:
<em>emphasized</em>
<em><b>emph & bold</b></em>
<a href="http://rubyonrails.org">A link</a>
<target option="fast" name="compile" />
Cualquier método con un bloque será tratado como una etiqueta de marcado XML con el
formato anidado en el bloque. Por ejemplo, los siguientes:
xml.div {
xml.h1(@person.name)
xml.p(@person.bio)
}
Produciría algo así como:
<div>
<h1>David Heinemeier Hansson</h1>
<p>A product of Danish Design during the Winter of '79...</p>
</div>
Parciales (Partials).- Plantillas partials - por lo general sólo llamadas " partials ". Con
partials, se puede extraer piezas de código de sus plantillas a archivos separados y
también volver a utilizarlos en sus plantillas.
26
Nomenclatura de partials.- Para poner un partials como parte de una vista, se utiliza
el método render dentro de la vista:
<%= render "menu" %>
Esto hará que un archivo llamado _menu.html.erb en ese momento se presente dentro de
la vista. Tenga en cuenta el caracter de guion bajo que lleva, los partials se nombran con
un guion bajo inicial para distinguirlos de puntos de vista regulares, a pesar de que se
hace referencia sin el guion bajo. Esto es cierto incluso cuando se está cogiendo un
parcial de otra carpeta:
<%= render "shared/menu" %>
Ese código coge el parcial de app/views/shared/_menu.html.erb.
Uso de Parciales para simplificar Vistas.- Una forma de utilizar los parciales es tratarlos
como el equivalente de subrutinas; una manera de mover datos de una vista para que
pueda entender lo que está pasando con mayor facilidad. Por ejemplo, es posible tener
una vista similar a la siguiente:
<%= render "shared/ad_banner" %>
<h1>Products</h1>
<p>Here are a few of our fine products:</p>
<% @products.each do |product| %>
<%= render partial: "product", locals: {product: product} %>
<% end %>
<%= render "shared/footer" %>
Aquí,
los
parciales _ad_banner.html.erb y _footer.html.erb podrían
incluir
contenido que se comparte entre muchas páginas en su aplicación. No es necesario ver
los detalles de estas secciones cuando se está concentrando en una página determinada.
Las opciones as and object .- Por defecto ActionView::Partials::PartialRenderer tiene
object en una variable local con el mismo nombre que la plantilla. Por lo tanto, dado:
<%= render partial: "product" %>
en product se obtiene @product en la variable local product, como si se escribiera:
<%= render partial: "product", locals: {product: @product} %>
27
Con la opción as se puede especificar un nombre diferente para la variable local. Por
ejemplo, si se quisiera que fuera item en lugar de product se haría:
<%= render partial: "product", as: "item" %>
La opción object se puede utilizar para especificar directamente el objeto que se
representa en el parcial; útil cuando el objeto de la plantilla está en otra parte (por
ejemplo. en una variable de instancia diferente o en una variable local).
Por ejemplo, en lugar de:
<%= render partial: "product", locals: {product: @item} %>
se haría:
<%= render partial: "product", object: @item %>
las opciones as y object también se pueden utilizar juntos:
<%= render partial: "product", object: @item, as: "item" %>
Layouts
Los diseños pueden ser utilizados para poner una plantilla de vista común en torno a los
resultados de las acciones del controlador Rails. “Por lo general, una aplicación Rails
tendrá un par de diseños de las páginas se presten. Por ejemplo, un sitio puede tener un
diseño para un usuario conectado y otro para la parte del sitio de marketing o ventas. El
diseño de inicio de sesión de usuario podría incluir la navegación a nivel superior que
debe estar presente en muchas acciones del controlador. La disposición de ventas para
una aplicación SaaS podría incluir la navegación de nivel superior para cosas como
precios y las páginas de Contacto” (DEV & Noria, s.f.).
Auxiliares para la generación de elementos de un formulario
Rails ofrece una serie de ayudas para la generación de elementos de un formulario, como
checkboxes, text fields, y radio buttons. Estos ayudantes básicos, con nombres que
terminan en funciones acabadas en _tag (como text_field_tag y check_box_tag ), generan
un solo elemento <input> . El primer parámetro a estos siempre es el nombre de la
28
entrada. Cuando se envía el formulario, el nombre será pasado junto con los datos del
formulario, y hará su camino al params hash en el controlador con el valor introducido por
el usuario para ese campo.
Al asignar nombres a las entradas, Rails utiliza ciertas convenciones que hacen posible
que presente los parámetros con los valores no escalares tales como matrices o hashes,
que también serán accesibles en params.
Las casillas de verificación (checkboxes).- Las casillas de verificación son los controles
del formulario que le dan al usuario un conjunto de opciones que se pueden activar o
desactivar:
<%=
<%=
<%=
<%=
check_box_tag(:pet_dog) %>
label_tag(:pet_dog, "I own a dog") %>
check_box_tag(:pet_cat) %>
label_tag(:pet_cat, "I own a cat") %>
Esto genera lo siguiente:
<input
<label
<input
<label
id="pet_dog" name="pet_dog" type="checkbox" value="1" />
for="pet_dog">I own a dog</label>
id="pet_cat" name="pet_cat" type="checkbox" value="1" />
for="pet_cat">I own a cat</label>
El primer parámetro a check_box_tag , por supuesto, es el nombre de la entrada. El
segundo parámetro, naturalmente, es el valor de la entrada. Este valor se incluye en los
datos del formulario cuando se marca la casilla de verificación.
Los botones de opción (Radio Buttons).- Los radio buttons, es similar a las casillas de
verificación, son los controles que especifican un conjunto de opciones en el que se
excluyen entre sí (es decir, el usuario sólo puede escoger uno):
<%= radio_button_tag(:age, "child") %>
<%= label_tag(:age_child, "I am younger than 21") %>
<%= radio_button_tag(:age, "adult") %>
<%= label_tag(:age_adult, "I'm over 21") %>
Salida:
<input id="age_child" name="age" type="radio" value="child" />
<label for="age_child">I am younger than 21</label>
<input id="age_adult" name="age" type="radio" value="adult" />
<label for="age_adult">I'm over 21</label>
29
Al igual que con check_box_tag , el segundo parámetro para radio_button_tag es el valor
de la entrada. Debido a que estos dos botones de radio comparten el mismo nombre ( la
edad ), el usuario sólo será capaz de seleccionar uno de ellos, y params[: edad] contendrá
ya sea "niño" o "adulto"
Otros métodos de interés
Otros controles del formulario que vale la pena mencionar son: áreas de texto, campos de
contraseña, campos ocultos, campos de búsqueda, campos de teléfono, los campos de
fecha, campos de hora, campos de color, los campos de fecha y hora, los campos de
fecha y hora local, campos de mes, los campos de la semana, los campos de URL,
campos de correo electrónico, número campos y campos de intervalo:
<%=
<%=
<%=
<%=
<%=
<%=
<%=
<%=
<%=
<%=
<%=
<%=
<%=
<%=
<%=
<%=
text_area_tag(:message, "Hi, nice site", size: "24x6") %>
password_field_tag(:password) %>
hidden_field_tag(:parent_id, "5") %>
search_field(:user, :name) %>
telephone_field(:user, :phone) %>
date_field(:user, :born_on) %>
datetime_field(:user, :meeting_time) %>
datetime_local_field(:user, :graduation_day) %>
month_field(:user, :birthday_month) %>
week_field(:user, :birthday_week) %>
url_field(:user, :homepage) %>
email_field(:user, :address) %>
color_field(:user, :favorite_color) %>
time_field(:task, :started_at) %>
number_field(:product, :price, in: 1.0..20.0, step: 0.5) %>
range_field(:product, :discount, in: 1..100) %>
Salida:
<textarea id="message" name="message" cols="24" rows="6">Hi, nice
site</textarea>
<input id="password" name="password" type="password" />
<input id="parent_id" name="parent_id" type="hidden" value="5" />
<input id="user_name" name="user[name]" type="search" />
<input id="user_phone" name="user[phone]" type="tel" />
<input id="user_born_on" name="user[born_on]" type="date" />
<input id="user_meeting_time" name="user[meeting_time]"
type="datetime" />
<input id="user_graduation_day" name="user[graduation_day]"
type="datetime-local" />
<input id="user_birthday_month" name="user[birthday_month]"
type="month" />
30
<input id="user_birthday_week" name="user[birthday_week]"
type="week" />
<input id="user_homepage" name="user[homepage]" type="url" />
<input id="user_address" name="user[address]" type="email" />
<input id="user_favorite_color" name="user[favorite_color]"
type="color" value="#000000" />
<input id="task_started_at" name="task[started_at]" type="time" />
<input id="product_price" max="20.0" min="1.0"
name="product[price]" step="0.5" type="number" />
<input id="product_discount" max="100" min="1"
name="product[discount]" type="range" />
1.2.3
Controlador (Controller)
Action Controller es la C en MVC. Después que el enrutamiento ha determinado
qué controlador se debe utilizar para una petición, el controlador se encarga de
que tome sentido la petición y producir la salida adecuada. Por suerte, Action
Controller hace la mayor parte de las bases y usa convenciones inteligentes para
hacer esto lo más sencillo posible.
Para la mayoría de las aplicaciones convencionales RESTful, el controlador
recibirá la solicitud (esto es invisible para el usuario como para el desarrollador),
busca o guarda los datos de un modelo y los utiliza a fin de crear una salida
HTML. Si el controlador tiene que hacer las cosas un poco diferentes, eso no es un
problema, esto es sólo la forma más común para que un controlador funcione.
(DEV & Noria, s.f.)
Un controlador de este modo puede ser pensado como un intermediario entre los modelos
y las vistas. Esto hace que los datos del modelo estén disponibles a la vista para que
pueda mostrar al usuario, y se guarda o actualizan los datos del usuario para el modelo.
Controlador de convención de nomenclatura
La convención de nomenclatura de los controladores en Rails favorece la pluralización de
la última palabra en el nombre del controlador, aunque no es estrictamente necesario
(ApplicationController ).
Por ejemplo, ClientsController es preferible a ClientController, SiteAdminsController es
preferible a SiteAdminController o SitesAdminsController , y así sucesivamente.
31
Siguiendo esta convención se permitirá utilizar los generadores de ruta por defecto sin
necesidad de calificar cada uno :path o :controller, y mantiene el uso de URL y ruta
de ayuda de uso constante a través de la aplicación.
La convención de nomenclatura controlador difiere de la convención de nombres de
modelos, que se espera que sea nombrado en forma singular.
Métodos y acciones
Un controlador es una clase que hereda de Ruby ApplicationController y tiene
métodos al igual que cualquier otra clase. Cuando la aplicación recibe una
petición, el enrutamiento determinará qué controlador y la acción a ejecutar, a
continuación, Rails crea una instancia de ese controlador y corre el método con el
mismo nombre que la acción. (DEV & Noria, s.f.)
class ClientsController < ApplicationController
def new
end
end
A modo de ejemplo, si un usuario va a la /clients/new en su aplicación para añadir un
nuevo cliente, Rails creará una instancia de ClientsController y ejecuta el método new.
Tenga en cuenta que el método vacío del ejemplo anterior podría funcionar muy bien
porque Rails por defecto crea la vistal new.html.erb a menos que la acción diga lo
contrario. El método new podría facilitar la vista de una variable de instancia @client
mediante la creación de un nuevo cliente:
def new
@client = Client.new
end
ApplicationController hereda de ActionController::Base, que define una serie de métodos
útiles. Sólo los métodos públicos son invocables como acciones. Es una mejor práctica
para reducir la visibilidad de los métodos que no están destinados a ser acciones, como
métodos o filtros auxiliares.
32
Parámetros
Es probable que desee acceder a los datos enviados por el usuario u otros parámetros en
sus acciones del controlador. Hay dos tipos de parámetros posibles en una aplicación
web. La primera son los parámetros que se envían como parte de la URL, llamados
parámetros de cadena de consulta. La cadena de consulta es todo lo que se encuentra
después de "?" en la URL. El segundo tipo de parámetro se refiere generalmente como
datos POST. Esta información generalmente proviene de un formulario HTML que ha sido
rellenado por el usuario. Se llama datos POST, ya que sólo puede ser enviado como parte
de una petición HTTP POST. Rails no hace ninguna distinción entre los parámetros de
cadena de consulta y parámetros POST, y ambos están disponibles en params hash en
su controlador:
class ClientsController < ApplicationController
def index
if params[:status] == "activated"
@clients = Client.activated
else
@clients = Client.inactivated
end
end
def create
@client = Client.new(params[:client])
if @client.save
redirect_to @client
else
render "new"
end
end
end
Sesión
Su aplicación tiene una sesión para cada usuario en la que puede almacenar pequeñas
cantidades de datos que se mantiene entre las solicitudes. La sesión sólo está disponible
en el controlador y la vista y se puede utilizar uno de una serie de diferentes mecanismos
de almacenamiento:

ActionDispatch::Session::CookieStore - Almacena todo en el cliente.

ActionDispatch::Session::CacheStore- almacena los datos en la caché de Rails.
33

ActionDispatch::Session::ActiveRecordStore- almacena los datos en una base de
datos usando Active Record. (requiere la gema activerecord-session_store).

ActionDispatch::Session::MemCacheStore- almacena los datos en un clúster de
memcached .
Todas las sesiones store utilizan una cookie para almacenar un identificador único para
cada sesión (debe utilizar una cookie, Rails no permitirá que se pase el identificador de
sesión en la URL, ya que es menos seguro).
Para la mayoría de las stores, este identificador se utiliza para buscar los datos de
la sesión en el servidor, por ejemplo, en una tabla de la base de datos. Hay una
excepción, y es el valor por defecto y de almacenamiento de sesión recomendado
- el CookieStore - que almacena todos los datos de la sesión en la propia cookie
(el ID todavía está disponible si lo necesita). Esto tiene la ventaja de ser muy sutil y
requiere de configuración cero en una nueva aplicación con el fin de utilizar la
sesión. Los datos de cookie se firman criptográficamente para que sea a prueba
de manipulaciones. Y también está cifrada para que cualquier persona con acceso
a la misma no pueda leer su contenido. (Rails no lo aceptará si ha sido editado).
El CookieStore puede almacenar alrededor de 4 KB de datos - mucho menos que
los otros - pero esto suele ser suficiente. El almacenamiento de grandes
cantidades de datos en la sesión no se recomienda sin importar el
almacenamiento de sesión que utiliza su aplicación. Especialmente debe evitar el
almacenamiento de objetos complejos en la sesión (que no sean objetos de Ruby
básicos, el ejemplo más común son instancias de modelo), ya que el servidor
podría no ser capaz de volver a unirlos entre las solicitudes, lo que resultará un
error.
Si sus sesiones de los usuarios no almacenan datos críticos o no necesitan estar
allí por largos períodos de tiempo (por ejemplo, si sólo se utiliza el flash para la
mensajería),
se
puede
considerar
el
uso
de ActionDispatch::Session::CacheStore. Esto almacenará sesiones utilizando el
caché que se ha configurado para su aplicación. La ventaja de esto es que se
puede utilizar su infraestructura de caché existente para almacenar las sesiones
sin requerir ninguna configuración o administración adicional. La desventaja, por
34
supuesto, es que las sesiones serán efímeras y podrían desaparecer en cualquier
momento. (DEV & Noria, s.f.)
Routes (Rutas)
“El framework como tal trae documentación que corresponde a las diferentes formas
como configurar el archivo de las rutas que se encuentra en el archivo config/routes.rb”
(DEV & Noria, s.f.).
Cuando el framework recibe una petición de parte del usuario para desplegar cierta
información lo primero que analiza es la ruta que se escribió en el navegador,
principalmente se enfoca en lo que esta después del dominio.
Aparte del path o ruta también se analiza el verbo (métodos de petición) de http con la
que la petición se envió, http es un protocolo orientado a transacciones y sigue el
esquema petición-respuesta entre un cliente y un servidor. Entre los verbos con los que
rails trabaja son: GET, POST, PATCH, PUT, DELETE entre otras.
En Rails, una ruta de recursos proporciona una correspondencia entre los verbos HTTP y
URLs a las acciones de controladores. Por convención, cada acción también se asigna a
las operaciones CRUD particulares en una base de datos. Una sola entrada en el archivo
de rutas, tales como:
resources :products
Crea siete rutas diferentes en su aplicación, todo el mapeo del controlador products:
HTTP
verbal
GET
GET
Camino
POST
GET
GET
/products
products#create
/products/:id
products#show
/products/:id/editproducts#edit
/products
/products/new
PATCH/PUT /products/:id
DELETE
/products/:id
controlador
Acción
products#index
products#new
products#update
products#destroy
#Usado para
mostrar una lista de todos los productos
devolver un formulario HTML para la
creación de un nuevo producto
crear un nuevo producto
mostrar un producto específico
devolver un formulario HTML para editar
un producto
actualizar un producto específico
eliminar un producto específico
Tabla 1. Rutas de recursos (DEV & Noria, s.f.)
35
Por defecto, Rails crea rutas para las siete acciones predeterminadas (index, show new,
create, edit, update y destroy). Se puede utilizar las opciones :only y :except para
afinar este comportamiento.
La opcion :only le dice a Rails para crear sólo las rutas especificadas:
resources :products, only: [:index, :show]
La opcion :except especifica una ruta o lista de rutas que Rails no debería crear:
resources :photos, except: :destroy
Si la aplicación tiene muchas rutas RESTful, usando :only y :except que generan sólo
las rutas que en realidad se necesita se puede reducir el consumo de memoria y acelerar
el proceso de enrutamiento.
36
2. METODOLOGÍA DE DESARROLLO
2.1
Tipo de la Investigación
La investigación es aplicada y bibliográfica la que en primera instancia busca transformar
el conocimiento puro existente en conocimiento útil y tiene como finalidad la búsqueda y
consolidación del saber.
Según su finalidad es aplicada ya que “busca la aplicación o utilización de los
conocimientos que se adquieren” (BEHAR, 2008).
Según su enfoque bibliográfica ya que: “La adquisición u obtención del conocimiento, la
fijación, organización y ampliación del mismo así como su transmisión, requieren de
normas especiales, de una metodología que precise y eduque en pensamiento y la
expresión, que los estimulen y fortalezcan. Así pues, el método es un proceso lógico,
surgido del raciocinio y de la inducción” (DE LA TORRE VILLAR & NAVARRO DE ANDA,
1990).
2.2
Población
Son los documentos existentes en bibliografía escrita sobre Ruby on Rails versión 4,
existentes en la web de manera libre.
La selección se realizará utilizando el: criterio de la pertinencia significa que las
fuentes consultadas deben ser acordes con el objeto de investigación y con sus
objetivos, en tanto en cuanto aportar conocimientos, enfoques, teorías, conceptos
y/o
experiencias
significativas
para
(RODRIGUEZ U, 2013)
37
fundamentar
la
propia
investigación.
2.3
Método de Investigación
El método empleado es analítico, lo que se busca es partir del todo que es el desarrollo
sobre Ruby on Rails y analizar sus partes para conocer, su funcionamiento, vinculaciones
y cualidades.
Analítico: El Método analítico es aquel método de investigación que consiste en la
desmembración de un todo, descomponiéndolo en sus partes o elementos para
observar las causas, la naturaleza y los efectos. El análisis es la observación y
examen de un hecho en particular. Es necesario conocer la naturaleza del
fenómeno y objeto que se estudia para comprender su esencia. Este método nos
permite conocer más del objeto de estudio, con lo cual se puede: explicar, hacer
analogías, comprender mejor su comportamiento y establecer nuevas teorías.
(ORTIZ & GARCIA, 2005)
La investigación se realiza en torno a la búsqueda de información sobre el desarrollo de
aplicaciones web utilizando Ruby on Rails.
Se realiza la búsqueda en la web y se aplicará los detalles con el desarrollo del ejemplo
práctico, el mismo que viajará durante todo el desarrollo de la investigación.
38
3. CALCULOS Y RESULTADOS
En lo que sigue se realiza paso a paso dos ejemplos: el primero en el que se explica
básicamente la funcionalidad de Rails y en el segundo una aplicación más completa que
utiliza en lo posible todo lo expuesto en el Marco teórico.
3.1
Paquete de Instalación
Iniciarse en Rails sobre Windows es relativamente fácil gracias a los esfuerzos de Engine
Yard (http://engineyard.com) que han desarrollado RailsInstaller (http://railsinstaller.org/),
un instalador en un sólo paquete de todas las herramientas que se necesita para ponerle
a trabajar, incluido Rails.
En su última versión railsinstaller 3.1.1 se encuentra: Ruby 2.1.8, Rails 4.2.5.1,
activerecord-sqlserver-adapter 4.2.6, coffee-rails 4.1.1, jquery-rails 4.1.0, sass-rails 5.0.4,
SQLite 3.8.7.2, MySQL 5.6.21, Bundler, Git, TinyTDS y DevKit
3.2
Instalación y configuración
Ejecutar el archivo de instalación desde la ubicación donde se encuentre descargado.
Realizar la instalación típica de Windows.
Figura 8. Ventana de instalación de Ruby/Rails
39
Escoger la ubicación para la instalación y seleccionar todas las opciones e instalar
Figura 9. Ventana para seleccionar la ubicación
Al finalizar la instalación, se muestra la consola de sistema CMD o terminal para
configurar los datos de Git (nombre, email).
Para poder verificar las versiones de Ruby y Rails se ejecuta los siguientes comandos.
Con lo que se puede verificar la instalación correcta de Ruby y Rails.
C:\Sites>ruby –v
C:\Sites>rails -v
El siguiente paso es instalar las gemas necesarias para el funcionamiento, que se las
puede descargar desde la página siguiente.
https://rubygems.org/pages/download
Descomprimir el archivo .zip de gemas, ingresar al directorio desde el terminal y ejecutar
el siguiente código:
C:\rubygems-2.5.2>ruby setup.rb
Para finalizar la instalación y evitar posibles errores con MySQL se ejecuta:
C:\Sites>gem install mysql2
40
Es necesario instalar el programa nodejs que se lo puede descargar desde
(https://nodejs.org/en/) esto es de ayuda en la solución de posibles errores, la instalacion
es muy sencilla, al terminar la instalación y si el terminal CMD se encuentra en ejecución
cerrarlo y volverlo a abrir para que los cambios tengan efecto.
3.3
Mi primera aplicación
3.3.1
Creación de los recursos
Para crear varios procesos en Rails se usará el símbolo de sistema (cmd) de Windows se
inicia presentando algunos comandos básicos.

CD.- Muestra el nombre o cambia al directorio actual.

CLS.- Borra los símbolos o el texto en la pantalla de la consola.

COPY.- Copia uno o más archivos en otra ubicación.

DEL.- Elimina uno o más archivos.

DIR.- Muestra una lista de archivos y subdirectorios en un directorio.
Rails tiene una serie de comandos llamados generadores que están diseñados para hacer
el desarrollo más fácil mediante la creación de todo lo que es necesario para empezar a
trabajar en una tarea en particular. Uno de ellos es el generador de nuevas aplicaciones,
lo que le proporcionará la base de una aplicación Rails.
Para utilizar este generador, se tiene que abrir un terminal CMD, navegar a un directorio
en el que se tenga derechos para crear archivos, por lo general Rails crea una carpeta
llamada Sites en el disco local C:, para situarnos en ella se debe editar lo siguiente:
cd c:\Sites, la cual se usa para comenzar con la descripción de la herramienta,
entonces para crear una nueva aplicación se escribe:
C:\Sites>rails new AppWeb
esto creará una aplicación Rails llamada AppWeb en el directorio AppWeb e instala
automáticamente las dependencias de gemas utilizando el comando internamente
bundle install.
41
Opcionalmente puede ver todas las opciones de línea de comandos que el generador de
aplicaciones Rails acepta mediante la ejecución de:
C:\Sites>rails new -h
Después de crear la aplicación, debe ingresar al directorio AppWeb, así:
C:\Sites>cd AppWeb
El directorio
de AppWeb tiene un número de archivos y carpetas generadas
automáticamente que componen la estructura de una aplicación Rails. Lo que se vería de
la siguiente forma en una ventana de Windows.
Figura 10. Directorio AppWeb
La mayor parte del trabajo va a pasar en la carpeta app, pero aquí hay un resumen básico
de la función de cada uno de los archivos y carpetas que Rails creó de forma
predeterminada:
42
Carpeta
app /
Propósito
Contiene los controladores, modelos, vistas, ayudas, entre otros para su
aplicación. La mayoría de actividades se centra en esta carpeta.
bin/
Contiene los script de rails para ejecutar la aplicación y puede contener
otras script de comandos que se utilizan para la configuración e
implementación de la aplicación.
config /
Configurar las rutas de su aplicación, base de datos, y mucho más.
config.ru
Configuración de rack para servidores basados en rack utilizados para
iniciar la aplicación.
db /
Contiene el esquema de base de datos actual, así como las migraciones
de bases de datos.
Gemfile
Estos archivos permiten especificar qué dependencias de gemas se
Gemfile.lock
desee para su aplicación Rails. Estos archivos son utilizados por la
gema Bundler.
lib /
Módulos de expansión para su aplicación.
log/
Archivos de registro de aplicación.
public/
La única carpeta visible para el público. Contiene los archivos estáticos y
activos compilados.
Rakefile
Este archivo localiza y carga las tareas que se pueden ejecutar desde la
línea de comandos. Las definiciones de tareas se definen a través de los
componentes de rails.
README.rdoc Este es un breve manual de instrucciones para su aplicación. Debe
editar este archivo para decir a los demás lo que hace su aplicación,
cómo configurarlo, y así sucesivamente.
test/
Las pruebas unitarias, accesorios y otros equipos de prueba.
tmp/
Los archivos temporales (como los archivos de caché, pid, y de sesión).
vendor/
Un espacio para todo el código de terceros en una aplicación típica rails
esto incluye gemas externas.
Tabla 2. Archivos y Carpetas creadas
Para empezar, es necesario presentar un poco de texto en la página web
rápidamente. Para ello, es necesario tener el servidor de aplicaciones de Rails en
ejecución, procedimiento que se explica en lo que sigue.
3.3.2
Poner en marcha el servidor Web
De hecho, se tiene una aplicación Rails funcional. Para verlo, se necesita iniciar un
servidor web en el equipo de desarrollo. Puede hacer esto mediante la ejecución del
siguiente comando en el directorio de la aplicación:
C:\Sites\AppWeb>rails server
O a su vez en su forma más compacta rails s
43
Esto
lanzará
WEBrick,
un
servidor
web
distribuido
con
Ruby
de
forma
predeterminada. Para ver su aplicación en acción, abra una ventana del navegador y vaya
a http://localhost:3000. Debería ver la página de información por defecto de Rails
así:
Figura 11. WEBrick
Si el servidor no pudo iniciar y muestra un error que informa que corra el comando
bundle install para solucionarlo, esto se debe por alguna incompatibilidad de la
versión de Windows por lo que no pudo ejecutar automáticamente el comando bundle
install al crear el proyecto.
Para detener el servidor web, pulse Ctrl + C en la ventana de terminal en el que se está
ejecutando. En el modo de desarrollo, Rails por lo general no requiere que se reinicie el
servidor; los cambios que realice en los archivos serán recogidos automáticamente por el
servidor.
La página "Home" es la prueba de fuego para una nueva aplicación Rails. Se asegura de
que tiene su software configurado correctamente suficiente para ejecutar una página web.
Lo que se vera en lo que sigue.
44
3.3.3
Hola, Rails
Para mostrar a Rails diciendo "Hola, Rails!", se necesita crear, como mínimo,
un controlador y una vista.
El propósito de un controlador es recibir solicitudes específicas para la aplicación. El
enrutamiento (Routing) decide cuál controlador recibe lo que se pide. A menudo, hay más
de una ruta para cada controlador, y las diferentes rutas pueden servir a
diferentes acciones. El propósito
de
cada
acción
es
recoger
información
para
proporcionarla a una vista.
El propósito de una vista es para mostrar la información en un formato legible. Una
distinción importante es que donde se recoge la información o datos que desea
administrar es el controlador, no la vista. La vista simplemente debe mostrar esa
información.
Para crear un nuevo controlador, se tendrá que ejecutar el generador de "controladores" y
decirle que quiere un controlador llamado "home" con una acción llamada "index”.
C:\Sites\AppWeb> rails generate controller home index
Rails creará varios archivos en los directorios /app/controllers/ y /app/views/
este último contiene una carpeta con el nombre del controlador en este caso home.
Los
archivos
más
importantes
de
éstos
en app/controllers/home_controller.rb
y
son,
el
la
vista,
controlador,
que
se
ubicado
encuentra
en app/views/home/index.html.erb.
Abrir el archivo app/views/home/index.html.erb en el editor de texto de su
preferencia (SublimeText, Brackets, Notepad ++, entre otros). En lo que sigue se trabaja
en el directorio C:\Sites\AppWeb que es donde se encuentran todos los archivos
necesarios. Ahora en el archivo abierto eliminar todo el código existente en el archivo, y
reemplazarlo con la siguiente línea de código:
<h1> Hola, Rails!</h1>
45
Configuración de la Página de Inicio (Root)
Ahora que se creó el controlador y vista, se tiene que decirle a rails cuando se requiere
mostrar la vista que contiene “Hola, Rails!". En este caso, se quiere que aparezca cuando
se navegue a la URL raíz o root del sitio web, http://localhost:3000. Por el
momento, " la página de información de rails Welcome Aboard" está ocupando ese lugar.
Ahora, se tiene que indicarle a rails donde se encuentra su página principal home.
Para lo cual se debe abrir el archivo config/routes.rb. Este es el archivo de
enrutamiento de la aplicación, que contiene entradas con un DSL especial (lenguaje
específico de dominio) que le indica a rails cómo conectar las solicitudes entrantes a
controladores y acciones.
En el archivo se debe escribir root 'home#index' lo cual le indica a rails asociar
peticiones de la raíz de la aplicación a la acción index del controlador home y además
get
'home/index'
le
indica
a
rails
asociar
solicitudes
al
url
http://localhost:3000/home/index de la acción index del controlador. Este
último se creó cuando se ejecutó el generador del controlador (rails generate
controller home index).
Poner en marcha el servidor web nuevamente si se lo detuvo para generar el controlador
y luego dirigirse al url http://localhost:3000 en su navegador. Se muestra el
mensaje "Hola, Rails!" que se escribió en app/views/home/index.html.erb, lo que
indica que esta nueva ruta es en realidad la acción del index de homeController y
está prestando la vista correctamente.
Figura 12 Hola Rails!
46
Con esto se ha realizado la primera parte del ejemplo utilizando Ruby on Rails y
mostrando la funcionalidad básica del mismo.
3.4
Aplicación web completa
Se desarrolla una aplicación web utilizando en lo posible toda la teoría expuesta en el
capítulo 1.
Se realizará un inventario de productos de una empresa distribuidora de los mismos, a la
cual se integran productos de diferentes proveedores, fabricantes y tipos. Además
contendrá un sistema de autenticación de usuarios. En la aplicación el administrador
podrá ser capaz de ver, crear, eliminar y actualizar los datos determinados de producto,
proveedor, fabricante y tipo. Para ver más a detalles el ejemplo con sus diagramas de
flujo y casos de uso dirigirse al Anexo E.
Configurar la conexión a la base de datos MySQL
Cabe recordar que se necesita que se encuentre instalado el motor de base de datos
MySQL para que las configuraciones se ejecuten con normalidad, se lo puede descargar
desde la url http://dev.mysql.com/downloads/windows/installer/5.7.html
Ahora bien buscar el archivo en la ruta conf/database.yml y remplazar el código:
development:
<<: *default
database: db/development.sqlite3
por lo siguiente:
development:
adapter: mysql2
username: root
password: 1234
host: 127.0.0.1
port: 3306
database: appWeb #nombre de su base de datos
pool: 5
timeout: 5000
se tiene que asegurar de que exista dos espacio antes de la palabra desde la segunda
hasta la última línea del código anterior para evitar errores, cambiar username, password
47
por los datos de acceso a su base de datos y en database escribir el nombre de la base
de datos que se quiere crear, recuerde guardar los cambios realizados en este archivo.
Luego se aumenta estas líneas en el archivo /GemFile
gem 'mysql2'
y ejecutar el comando siguiente, para instalar las nuevas gemas que se ha colocado, si el
servidor se encuentra activo se debe detener:
C:\Sites\AppWeb> bundle install
La línea de código anterior se la debe ejecutar cada vez que se coloque una nueva gema.
Una vez instalada la gema, se las actualiza utilizando el siguiente código para solucionar
posibles incompatibilidades con gemas instaladas anteriormente:
C:\Sites\AppWeb> bundle update
Para construir la base de datos desde cero a partir de la configuración realizada en el
archivo config/database.yml; se ejecuta el comando de la siguiente forma:
C:\Sites\AppWeb> rake db:create
lo que realizo la línea anterior es crear la base de datos en el gestor de base de datos
MySQL. Sin que se haya ni siquiera ingresado al mismo MySQL.
Si no se pudo ejecutar el comando rake db:create debido a un error, ejecutar el
comando gem update –system para resolverlo y con esto ya se podrá ejecutar.
Ahora se crea los modelos, las vistas y los controladores, para el ejemplo planteado,
según el siguiente esquema:
48
Figura 13. Modelo Entidad Relación
3.4.1
Creación de Modelos
Mediante el generador scaffold se crean los modelos, las vistas y los controladores,
este generador es de gran ayuda para no realizar una por una cada acción.
Rails está familiarizado con el idioma ingles para realizar las convenciones sobre la
singularidad y la pluralidad de los modelos, por lo dicho algunos modelos no se plurizaran
correctamente en este caso Proveedor se plurizara como Proveedors.
Ahora para el ejemplo se ejecuta el generador scaffold para el modelo TipoProducto
que contiene los campos nombre y descripción.
C:\Sites\AppWeb>rails generate scaffold TipoProducto nombre:string
descripcion:text
Luego para migrar el modelo creado en el paso anterior a la base de datos MySQL se
ejecuta lo siguiente, ya que scafford también creo la migración automáticamente:
C:\Sites\AppWeb>rake db:migrate
Cada vez que se ejecute el generador scaffold se debe realizar la migración con la
línea que antecede. La creación correcta del modelo TipoProducto, puede verificar en la
url http://localhost:3000/tipo_productos, con el servidor en ejecución. Se
presenta una página web con las acciones de crear, leer, actualizar y eliminar:
49
Figura 14. Vista Tipos de Productos
Ahora nuevamente utilizando el generador scaffold se crea el modelo Fabricante
con los campos nombreFab y descripcionFab.
C:\Sites\AppWeb>rails generate scaffold Fabricante
nombreFab:string descripcionFab:text
migrar el modelo creado (rake db:migrate). Se verifica la creación del modelo en
http://localhost:3000/fabricantes lo que muestra.
Figura 15. Vista de Fabricante
Para el ejemplo que se desarrolla se crea con scaffold todos los modelos con lo que
automáticamente se crean las vistas y los controladores.
50
3.4.2
Modelo uno a muchos
Se crea el modelo Producto que contiene los campos nombre, descripcion, precio,
fecha, tipo_producto y fabricante estos dos últimos son campos que hacen
referencia a la asociación de 1:n (uno a muchos) con los otros modelos creados
anteriormente y automáticamente los vincula con sus foreign_key, también coloca las
asociaciones en su controlador:
C:\Sites\AppWeb>rails generate scaffold Producto nombre:string
descripcion:text precio:decimal fecha:time cantidad:integer
tipo_producto:references fabricante:references
migrar el modelo creado (rake
db:migrate) y verificar el modelo en la url
http://localhost:3000/productos, lo que muestra.
Figura 16. Vista Producto
Tener en cuenta que en la creación de modelo producto hace referencia entre
tipoProducto y fabricante con el comando :reference esto es lo que produce la
asociación de uno a muchos.
51
3.4.3
Modelo muchos a muchos
Crear el modelo para el proveedor Proveedor que contiene los campos nombre, ruc,
telefono, dirección,
email y ciudad, se usa este modelo para vincular la
asociación de muchos a muchos con el modelo Producto.
C:\Sites\AppWeb>rails generate scaffold Proveedor nombre:string
ruc:integer telefono:integer direccion:text email:string
ciudad:string
migrar el modelo creado (rake db:migrate). Se podrá ver las vistas del modelo en la url
http://localhost:3000/proveedors como se muestra a continuación.
Figura 17. Vista Proveedor
Como una asociación de muchos a muchos necesita un modelo intermedio para la
asociación entre estos modelos, se crea el modelo que se usará como conexión entre
Proveedor y Producto, el modelo se lo define de la siguiente forma:
C:\Sites\AppWeb>rails g migration CreateJoinTableProductoProveedor
producto proveedor
migrar el modelo creado (rake db:migrate). También se debe colocar la asociación en
cada uno de los modelos, escribir en los archivos de modelos que se encuentran en el
directorio /app/models como se observa:
52
class Proveedor < ActiveRecord::Base
has_and_belongs_to_many :productos
end
y
class Producto < ActiveRecord::Base
belongs_to :tipo_producto
belongs_to :fabricante
has_and_belongs_to_many :proveedors
end
como último paso en el archivo /app/controller/productoController.rb se tiene
que crear el parámetro {:proveedor_ids => []} que recibirá el controlador de
Producto dentro del método producto_params quedando de la siguiente forma:
def producto_params
params.require(:producto).permit(:nombre, :descripcion, :precio,
:fecha, :tipo_producto_id, :fabricante_id, {:proveedor_ids => []})
end
con lo que se finaliza la creación de los modelos, las vistas y los controladores que
gracias al generador scafford se realizó de una manera más sencilla.
3.4.4
Actualizar o crear campos
Al realizar este proceso de generación de modelos a veces se puede omitir la creación de
algún campo o su vez querer cambiar el nombre o tipo de dato de los que se ha creado,
para ello Rails tiene algunas funcionalidades específicas.
Para nuestro ejemplo se cambia el tipo de dato del campo fecha de la tabla productos:
del tipo time a date, y se aumentará los números de caracteres del campo ruc en el
modelo proveedors. Generar lo siguiente:
C:\Sites\AppWeb>rails g migration cambiar_tipos_de_datos
lo que genera es un archivo en el directorio /db/migrate/
con el nombre
YYYYMMDDhhmmss_cambiar_tipos_de_datos.rb, el cual será editado para realizar los
cambios previstos:
53
class CambiarTiposDeDatos < ActiveRecord::Migration
def change
change_column :productos, :fecha, :Date
change_column :proveedors, :ruc, :integer, :limit => 8
change_column :proveedors, :telefono, :integer, :limit => 8
end
end
y como se ha venido repitiendo se debe realizar la migración,
C:\Sites\AppWeb>rake db:migrate
cabe recordar que si crea un campo nuevo en cualquier modelo, se tiene que agregar a
los parámetros que recibirá el controlador, por ejemplo si se crea un campo link en
productos se lo agregaría en el método producto_params, ya que sin este no podrá
recibir la solicitud para guardarse en la base de datos:
def producto_params
params.require(:producto).permit(:nombre, :descripcion,
:precio, :fecha, :tipo_producto_id, :fabricante_id,:link )
end
este código no es parte del ejemplo que se está desarrollando pero es fundamental en la
creación de nuevos campos.
Una forma genérica para cambiar el nombre, el tipo de dato, o agregar un campo en
primera instancia crear un archivo de migración que se lo realiza de la siguiente forma:
C:\Sites\AppWeb>rails g migration nombre_migracion
Así mismo existen varios comandos para diferentes funcionalidades como por ejemplo
renombrar, crear o cambiar el tipo de un campo,
change_column :nombreTabla, :nombreColumna, :tipoDato
rename_column :nombreTabla, :nombreColumna, :nuevoNombreColumna
add_column :nombreTabla, :nombreColumna, :tipoDato
Ejemplo:
change_column :products, :fecha, :Date
rename_column :product_types, :descripcion, :descripcionType
add_column :manufacturers, :link, :text
54
3.4.5
Crear Campos para archivos
Existe una forma de crear campos para el manejo de archivos, pero primero se deben
instalar algunas gemas para que funcione correctamente.
Se empieza por instalar la gema paperclip pero esta funciona con la aplicación
ImageMagick por lo que primero se debe instalar esta aplicación, ImageMagick está
distribuido para Windows, Linux y MAC. La aplicación que se instalará es ImageMagick6.9.3-7-Q16-x64-dll.exe en su versión para Windows y se la puede encontrar en el link
http://www.imagemagick.org/script/binary-releases.php#windows
La instalación de esta aplicación es la típica de Windows con solo seguir el botón next.
Figura 18. ImageMagick
Para un buen funcionamiento con Rails deben estar seleccionados las opciones que se
muestran en la siguiente imagen, y finalmente completar la instalación,
Figura 19. ImageMagick Tasks
55
para comprobar que la aplicación se instaló correctamente se debe abrir el terminal (si se
encuentra abierto se lo debe cerrar y volver a abrir para que los cambios surtan efecto) y
escribir convert –version con lo cual nos muestra la versión de la aplicación.
C:\Sites\AppWeb>convert -version
Ahora se debe editar el archivo de GemFile y colocar la gema paperclip,
gem 'paperclip'
Luego de haber colocado la gema se debe instalar con el comando: bundle install
Además para corregir errores de compatibilidad con la versión 4 de paperclip se debe
crear
manualmente
un
archivo
llamado
paperclip.rb
en
el
directorio
/config/initializer/ que contendrá el siguiente código:
require 'paperclip/media_type_spoof_detector'
module Paperclip
class MediaTypeSpoofDetector
def spoofed?
false
end
end
end
ya realizada la instalación ahora se crea el campo de manejo de archivos para el ejemplo.
Se crea un campo para el manejo de la imagen del fabricante y el producto llamado
urlImagen; primero se crea el archivo de migración como lo se vio anteriormente.
C:\Sites\AppWeb>rails g migration add_urlImagen
lo que genera es un archivo en el directorio /db/migrate/
con el nombre
YYYYMMDDhhmmss_ add_urlImagen.rb, el cual será editado para realizar los cambios
previstos:
class AddUrlImagen < ActiveRecord::Migration
def change
add_attachment :fabricantes, :urlImagen
add_attachment :productos, :urlImagen
end
end
56
luego migrar el archivo (rake db:migrate), con lo cual se crean 4 campos en cada
tabla de la base de datos que sirven para el manejo de los datos de archivos por parte de
la
gema
paperclip,
esto
lo
realiza
automáticamente:
urlImagen_file_name,
urlImagen_content_type, urlImagen_file_size y urlImagen_updated_at
Como se dijo anteriormente se debe adicionar el parámetro en el método de su
controlador respectivo, el parámetro debe tener el nombre del campo urlImagen como
se observa en cada uno de los respectivos controladores:
def fabricante_params
params.require(:fabricante).permit(:nombreFab,
:descripcionFab, :urlImagen)
end
----------------------------------------------------------------def producto_params
params.require(:producto).permit(:nombre, :descripcion,
:precio, :fecha, :tipo_producto_id, :fabricante_id,
{:proveedor_ids => []}, :urlImagen)
end
Finalmente se debe agregar las validaciones que paperclip necesita en el modelo
fabricante y producto respectivamente para que integre toda la funcionalidad de la gema:
class Fabricante < ActiveRecord::Base
has_attached_file :urlImagen, style: {medium: "1280x720"}
validates_attachment_content_type :urlImagen, :content_type =>
/\Aimage/
end
-----------------------------------------------------------------class Producto < ActiveRecord::Base
belongs_to :tipo_producto
belongs_to :fabricante
has_and_belongs_to_many :proveedors
has_attached_file :urlImagen, style: {medium: "1280x720"}
validates_attachment_content_type :urlImagen, :content_type =>
/\Aimage/
end
basicamente la primera línea informa que tiene un archivo adjunto que se vincula con el
campo que se creó, además se le ha colocado la opción de estilos para el manejo de
imágenes por ImageMagick que lo que hace es; a cualquier imagen que se cargue se
cree una copia con las dimensiones especificadas, esta última parte es opcional, la
segunda línea valida el campo y el contenido que debe tener en este caso solo imágenes.
57
3.4.6
Manejo de Vistas
Ahora se comienza a editar las vistas para aumentar los campos necesarios o cambiar lo
que creó automáticamente scaffold. Primero se debe verificar que en el directorio
/app/view se han creado varios directorios con los nombre de los modelos, además en
el interior de cada uno se encuentran varios archivos con extensión html.erb entre los que
se destacan index, edit, new, show y una vista parcial _form, el código de estos
archivos son muy entendibles, así que no será difícil saber qué hace cada uno.
Vista Fabricante
Crear el campo para el manejo de archivos en la vista fabricante. Editar el archivo
parcial _form.html.erb de fabricantes para colocar el campo de imagen que se
creó en el modelo, colocando el código:
<div class="field">
<%= f.label 'Url Imagen' %><br><%= f.file_field :urlImagen %>
</div>
Visualizándolo de la siguiente manera:
Figura 20. Vista Fabricante Editada
Aumentar en el archivo show.html.erb el código para visualizar la imagen que se cargó
en el modelo:
<p><strong>Imagen:</strong></p>
<div><%= image_tag @fabricante.urlImagen.url() %></div>
Resultado lo siguiente:
58
Figura 21. Vista Fabricante Show
y se puede colocar en el archivo index.html.erb el siguiente código, para visualizarlo
en la tabla de todos los registros manufacturers, en este caso se lo aumenta antes de
las etiquetas link_to, de la siguiente forma.
<td><%= image_tag fabricante.urlImagen.url() %></td>
Además se puede aumentar la clase a la etiqueta de tabla en todas las vistas así
<table class="table table-bordered table-striped">
Figura 22. Vista Fabricante Index
59
Vista Producto
A esta vista se le realizará varios cambios ya que el modelo contiene varias asociaciones.
En el archivo parcial _form.html.erb de producto se realiza los siguientes cambios:
Remplazar la etiqueta de entrada de precio que es tipo texto a números decimales
<%= f.text_field :precio %>
Remplazar por:
<%= f.number_field :precio, :class =>'text_field', :step => 0.1 %>
como se cambió el tipo de dato de fecha también se debe cambiar la etiqueta de entrada:
<%= f.time_select :fecha %>
Remplazar por:
<%= f.date_select :fecha %>
Para que nos muestre los valores de la asociación de tipo de producto y fabricante en un
elemento seleccionable que resulta una forma más amigable se remplaza los campos:
<%= f.text_field :tipo_producto_id %>
-----------------------------------------------------------------<%= f.text_field :fabricante_id %>
por los siguientes respectivamente:
<%= collection_select(:producto, :tipo_producto_id,
TipoProducto.all, :id, :nombre,{},{:multiple=>false}) %>
---------------------------------------------------------------<%= collection_select(:producto, :fabricante_id, Fabricante.all,
:id, :nombreFab,{},{:multiple=>false}) %>
Colocar el campo de imagen que se creó en el modelo, escribiendo el código:
<div class="field">
<%= f.label 'Url Imagen' %><br><%= f.file_field :urlImagen %>
</div>
Para mostrar la asociación de muchos a muchos con proveedor se inserta el código:
60
<div class="field">
<%= f.label :Proveedor %><br>
<% for proveedor in Proveedor.all %>
<tr>
<td><%= check_box_tag "producto[proveedor_ids][]",
proveedor.id, @producto. proveedors.include?(proveedor) %></td>
<td><%= proveedor.nombre %></td>
</tr>
<% end %>
</div>
Con lo que la vista se vería de la siguiente forma
Figura 23. Vista Producto Editada
En el archivo show.html.erb remplazar:
<p><strong>Tipo producto:</strong><%= @producto.tipo_producto %>
</p>
<p><strong>Fabricante:</strong> <%= @producto.fabricante %></p>
por:
61
<p>
<strong>Tipo de Producto:</strong>
<%= @producto.tipo_producto.nombre %>
</p>
<p>
<strong>Fabricante:</strong>
<%= @producto.fabricante.nombreFab %>
</p>
<h3>Proveedores</h3>
<ul>
<% @producto.proveedors.each do |proveedor| %>
<li><%= proveedor.nombre %></li>
<% end %>
</ul>
<p>
<strong>Imagen:</strong>
</p>
<div><%= image_tag @producto.urlImagen.url() %></div>
Lo que se visualizaría de la siguiente forma.
Figura 24. Vista Producto Show
y se puede colocar en el archivo index.html.erb el siguiente código, para visualizar en
la tabla de todos los registros productos, en este caso se lo aumenta antes de las
etiquetas link_to, de la siguiente forma.
<td><%= producto.tipo_producto.nombre %></td>
<td><%= producto.fabricante.nombreFab %></td>
<td><%= image_tag producto.urlImagen.url() %></td>
62
Quedando finalmente la página de productos así.
Figura 25. Vista Producto Index
3.4.7
Assets
En el directorio /app/assets, se guardan los estilos y JavaScrit que se utilizan en la
aplicación. Dentro de assets, se encuentran tres carpetas: images, javascripts y
stylesheets. Rails carga automáticamente las imágenes, JavaScripts y CSS que se
encuentran en las carpetas descritas y respectivamente.
En esta aplicación se utiliza las herramientas de diseño CSS y JavaScript predefinidos de
Bootstrap. Que se las puede descargar de: http://getbootstrap.com/, como sugerencia
puede el lector ingresar a http://www.w3schools.com/bootstrap/ para aprender más sobre
Bootstrap. Descomprimir el archivo .zip descargado y copiar los CSS y JavaScript que
este contiene a las respectivas carpetas de asset.
Adicionalmente se utiliza flexbox grid que nos facilita los CSS necesarios para trabajar
con bloques, se puede descargar de: http://flexboxgrid.com/, descomprimir el archivo .zip
descargado y copiar el archivo flexboxgrid.css que se encuentra en la carpeta css a la
carpeta respectiva de asset.
Menú de Navegación con Bootstrap
Crear una carpeta llamada parcial en el directrio /app/view, en el cual se creará un
archivo parcial llamado _cabecera.html.erb dentro de este se creará el menú de
navegación, con el siguiente código:
63
<div class="row center-xs">
<div class="col-sm-10">
<nav class="navbar navbar-inverse">
<div class="container-fluid">
<div class="navbar-header">
<a class="navbar-brand" href="#">AppWeb</a>
</div>
<ul class="nav navbar-nav">
<li class="active"><%= link_to "Home",root_path,:class =>
"navbar-brand", target:"_parent" %></li>
<li><%= link_to "Productos",productos_path, target:"_parent"
%></li>
<li><%= link_to "Fabricante",fabricantes_path,
target:"_parent" %></li>
<li><%= link_to "Tipos de Productos",tipo_productos_path,
target:"_parent" %></li>
<li><%= link_to "Proveedores",proveedors_path,
target:"_parent" %></li>
</ul>
</div>
</nav>
</div>
</div>
ahora se llama a esta vista parcial desde el archivo /layouts/application.html.erb.
Application es la vista que contiene la estructura de la página web para todas las demás
vistas, se colocará el menú en esta vista para que se replique en las demás vistas, así:
<%= render "parcial/cabecera"%>
Quedando de la siguiente manera:
<!DOCTYPE html>
<html>
<head>
<title>AppWeb</title>
<%= stylesheet_link_tag
'application', media: 'all', 'dataturbolinks-track' => true %>
<%= javascript_include_tag 'application', 'data-turbolinkstrack' => true %>
<%= csrf_meta_tags %>
</head>
<body>
<%= render "parcial/cabecera"%>
<%= yield %>
</body>
</html>
64
Ahora puede ver el menú de navegación en todas las vistas de la aplicación.
Figura 26. Menu de Navegación
3.4.8
Validaciones
En esta sección se crean las validaciones para los modelos creados. Como este es un
ejemplo se desarrollan las validaciones básicas para la administración de cada modelo.
En el directorio /app/models/ se aumenta el código en los archivos de cada modelo.
Fabricante
El siguiente código realiza 3 validaciones la primera, es que la imagen del fabricante se
cargue correctamente, la segunda y tercera se realizan sobre el mismo campo valida que
el nombre no se encuentra vacío y que este sea único,
validates :urlImagen,presence: true
validates :nombreFab, presence: true, :uniqueness=> {
:case_sensitive => true }
Tipo de producto
En tipo de producto se realizan 3 validaciones sobre el campo nombre: que no sea vacío,
que sea único y que contenga solo caracteres de letras:
validates :nombre, presence: true, :uniqueness=> { :case_sensitive
=> true },format: { with: /\A[a-zA-ZñÑáéíóú]+\s?+[a-zAZñÑáéíóú]+\z/}
65
Proveedor
Sobre el campo ruc la validación es que contenga entre 10 y 13 caracteres, y se muestra
un mensaje cuando no cumple la validación. En el campo teléfono la validación es
parecida a la anterior cambiando el número de caracteres entre 9 y 10. En el nombre se
valida que no sea vacío y que sea único. En el mail valida que no esté vacío, que sea
único y que tenga el formato de mail, si no pasa alguna validación dará un mensaje de
error. En los campos de dirección y ciudad que no se encuentran vacíos.
validates :ruc, length: { in: 10..13 , message: "debe tener entre
10 y 13 caracteres"}
validates :telefono, length: { in: 9..10 , message: "debe tener
entre 9 y 10 caracteres"}
validates :nombre, presence: true,:uniqueness=> { :case_sensitive
=> true }
validates :email, presence: true, :uniqueness=> { :case_sensitive
=> true }, format: { with: /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[az]{2,})\z/i, message: "El formato del correo es invalido" }
validates :direccion, presence: true
validates :ciudad, presence: true
Producto
En el campo nombre se valida que este no sea vacío y que sea único. El precio que no
sea vacío y tenga formato decimal. La descripción que no sea vacío. El campo de imagen
no este vacío.
validates :nombre, presence: true, :uniqueness=> { :case_sensitive
=> true }
validates :precio, presence: true, format: { with: /\d/}
validates :descripcion, presence: true
validates :urlImagen,presence: true
De ahora en adelante no podrá crear ni actualizar registros en los modelos si no cumple
las validaciones. Además el modelo producto solo crea o actualiza registros si los
registros de los otros modelos con los cual esta asociado están validados correctamente.
3.4.9
Buscador y paginación
El buscador permite encontrar de manera más ágil un producto, fabricante o un
proveedor, desde la vista de cada modelo.
66
Es necesario instalar una gema en el archivo GemFile, la misma que provee de ayudas en
el desarrollo del buscador. Para lo cual se debe escribir lo siguiente:
gem 'kaminari'
lo anterior solo define que se utilizará kaminari en la aplicación.
Luego se ejecuta el siguiente código para instalar la nueva gema que se colocó:
C:\Sites\AppWeb>bundle install
Se realiza el buscador para el modelo Producto, en el archivo del controlador
/app/controllers/productos_controller.rb se cambia el método index
sustituyendo la línea:
@productos = Producto.all
por lo siguiente:
if params[:search]
@productos =
Producto.search(params[:search]).order("nombre").page(params[:page
]).per(10)
else
@productos =
Producto.order("nombre").page(params[:page]).per(10)
end
En el archivo de modelo /app/models/producto.rb crear el siguiente método:
def self.search(search)
where('nombre LIKE ?', "%#{search}%")
end
Ahora crear el buscador en la vista de Producto, editar el archivo index.html.erb,
colocando lo siguiente sobre la tabla que se encuentra definida:
<%= form_tag productos_path, :method=> "get" do %>
<%= text_field_tag :search, params[:search], placeholder:
"Busqueda por nombre" %>
<%= submit_tag "Buscar",:nombre => nil %>
<% end %>
67
con esto se puede ver el campo y el botón de búsqueda en la vista index del producto.
Con la gema instalada previamente en esta sección, se puede crear también la
paginación. Colocar el siguiente código luego de la tabla para crear la paginación, cabe
decir que por la configuración en el controlador, realiza la paginación cada 10 registros:
<%= paginate @productos %>
Con lo expuesto en esta sección se encuentran funcional la búsqueda y paginación para
el modelo Producto.
Figura 27. Buscador
Se debe usar el mismo proceso para realizar la búsqueda y paginacion de los otros
modelos, cambiando lo que sea necesario para cada uno.
3.4.10 Autenticación de usuario
Es necesario instalar las 3 gemas en el archivo GemFile, la misma que provee de ayudas
en el desarrollo del registro y autenticación de usuario. De la siguiente manera:
gem 'devise'
gem 'devise-i18n'
gem 'devise-i18n-views'
lo anterior define que se utilizarán las 3 gemas de devise en la aplicación.
68
Instalar las gemas con lo siguiente:
C:\Sites\AppWeb>bundle install
Como se ha visto durante el desarrollo de este ejemplo cada vez que defina una gema se
debe instalar con el código anterior.
Esta gema requiere la instalación de toda su funcionalidad, así:
C:\Sites\AppWeb>rails g devise:install
una vez que finaliza la instalación aparecerá un mensaje con requisitos necesarios para
para utilizar devise.
Entre los cuales cabe destacar los más importantes:

Que se encuentre establecida la ruta principal en este caso del ejemplo: root
'home#index'.

Colocar
las
siguientes
líneas
de
código
en
la
ruta
app/views/layouts/application.html.erb
<p class="notice"><%= notice %></p>
<p class="alert"><%= alert %></p>
Ahora ya puede crear el modelo para registro y autenticación de usuarios en este caso
Usuario, use para esto el siguiente código:
C:\Sites\AppWeb>rails g devise Usuario
con lo anterior crea automáticamente: las vistas de inicio de sesión, registro de usuarios y
recuperación de contraseña con los campos :email y :encrypted_password además
de otros campos que los maneja automáticamente la gema.
Devise crea una autenticación más robusta no así si se crea una autenticación desde
cero, esta crea automáticamente los campos de contraseñas encriptados para que sea
más seguro, además crea variables para que el usuario pueda recuperar su contraseña.
Finalmente hay que migrar a la base de datos:
rake db:migrate
69
Ahora
ya
se
tiene
la
autenticación
de
usuarios
y
puede
verla
en
http://localhost:3000/usuarios/sign_in, esta vista también tiene links para
dirigirse a recuperar contraseña y registrarse. Si desea cambiarlos estilos de las vistas
que genero device puede dirigirse al Anexo A para más información
Figura 28. Inicio de Sesión
Toda la lógica de sesiones está en devise, no piense que devise es solo un plugin, ya que
este es de código abierto y se puede sobrescribir para que funcione como lo desee.
Además devise da varios métodos útiles para el control de inicio de sesión como
usuario_signed_in? , que verifica si el usuario inicio sesión o no correctamente, o
current_usuario.email que muestra el email del usuario autenticado, se utiliza el
código en el archivo parcial _cabecera.html.erb para demuestra lo expuesto:
<% if usuario_signed_in? %>
<%= current_usuario.email %>
<%= link_to "Cerrar Sesion", destroy_usuario_session_path,
method: :delete %>
<%else %>
<%= link_to "Iniciar Sesion", new_usuario_session_path %>
<%= link_to "Registrarse", new_usuario_registration_path %>
<% end %>
70
También se inserta el callback siguiente a los controladores que desee que no sea
accesible sin antes estar autenticado, estos controladores se encuentran en el directorio
/app/controllers/:
before_action :authenticate_usuario!
lo que hace es bloquear las rutas de los modelos de la aplicación, si se quiere ingresar sin
antes haberse autentificado, y las redirige a la ventana de inicio de sesión.
Figura 29. Autenticación
Terminado esto tendría una aplicación funcional culminando la segunda parte del ejemplo,
para ver el manejo de email ir a el Anexo C y para el manejo de sesiones ver ANEXO D,
bastaría trabajar con los estilos para que la aplicación tenga una mejor visualización, esto
dependerá del lector que puede hacerlo mediante CSS o gracias a las ayudas que trae
bootstrap y flexbox Grid.
Con esto se finaliza este tutorial de Ruby on Rails y es importante mencionar que se debe
analizar bien el código que se ha colocado para poder entender la razón por la cual
funciona y de esta manera generar conocimiento de calidad.
Se adjunta el proyecto terminado y ademas el proyecto mejorado con estilos como se
observa en las imágenes siguientes, las url de descarga se encuentran el la sección de
recomendaciones.
71
72
Figura 30. Aplicación aplicado estilos
73
4. DISCUSIÓN
Este trabajo tuvo como propósito presentar teorías fundamentales e introductorias sobre
Ruby on Rails, las mismas que se utilizan en el desarrollo de un ejemplo paso a paso y
que permite la introducción al desarrollo de aplicaciones web.
Durante el desarrollo de esta guía se encontró muy poco material escrito en español y
para el caso de Ecuador no se ha encontrado material escrito que introduzca a la
herramienta. A continuación se describe una discusión sobre los que se ha investigado
durante el desarrollo de este proyecto.
La evolución en el desarrollo de software no se detiene en el tiempo, y bajo esta premisa
se puede plantear dos estrategias, la primera quedarse con una tecnología determinada y
ser ineficiente o la segunda evolucionar en el tiempo. Esta última es la óptima, pero claro,
la primera es mucho menos costosa.
Una aplicación nueva, ahora no se plantea desarrollarla en COBOL, pues lo mismo
actualmente se puede aplicar con Java en la mayoría de contextos y próximamente en la
totalidad.
Según (MONTORO, 2013) dice en su página web, las discusiones sobre que lenguaje de
programación es mejor o más productivo suelen ser absurdas porque se basan casi
siempre en dos factores que casi nunca importan:

La productividad del lenguaje

La eficiencia en runtime
Si se dice que la productividad de un lenguaje se correlaciona directamente con el número
de líneas de código necesarias para escribir un algoritmo. En base a eso, un lenguaje
como RoR debería ser mucho más productivo que Java ¿o no? No necesariamente, por
dos motivos: primero porque casi ningún programador de Java escribe el código
74
directamente sino mediante asistentes que lo generan; y segundo porque sólo una
fracción del código son los algoritmos, habiendo un elevadísimo porcentaje del mismo que
son rutinas de control de errores y otras cosas. Es decir, la cantidad de líneas de código
necesarias para resolver un problema no es tan relevante como el tiempo real necesario
para producirlas y mantenerlas con las herramientas adecuadas.
Sobre la eficiencia en runtime se suele argumentar que el precio del ciclo de CPU es
ridículamente bajo, mientras que la hora de trabajo de un programador es terriblemente
cara. No necesariamente, porque la hora del programador, por cara que resulte, se paga
una sola vez y luego se amortiza en forma de un programa que funciona felizmente sin
problemas, pero un programa lento y mal hecho nunca deja de ser una caja de sorpresas.
Entonces ¿Qué cosas importan realmente en un lenguaje?, (MONTORO, 2013) dice lo
siguiente:

La disponibilidad de buenas herramientas y librerías.

La estabilidad de la plataforma.

La garantía de soporte a largo plazo.

La disponibilidad de mano de obra competente.

La interoperabilidad y compatibilidad con otro software.
Es típico ver cómo los usuarios que empiezan algo nuevo desde cero tienen tendencia a
usar PHP o Ruby on Rails porque es lo más fácil, mientras que los que ya tienen una
infraestructura Java o .NET tienen tendencia a mantenerla. Esto tiene toda la lógica del
mundo, una vez que se acostumbra a una plataforma, es muy difícil cambiarla.
Cuando se enfrenta por primera vez a código escrito en Ruby, probablemente recuerde
otros lenguajes que se haya usado. Esto es a propósito. La mayor parte de la sintaxis es
familiar para los usuarios de Perl, Python y Java (entre otros lenguajes), así que si se ha
usado alguno de estos, aprender Ruby es relativamente fácil.
MVC no es poco común, lo que es raro es la velocidad y la facilidad con la se puede crear
un sitio interactivo usando RoR y ActiveRecord. Es por eso que se recomienda que se
pruebe la tecnología. Y lo más importante, puede obtener esta velocidad sin sacrificar la
calidad del producto final.
75
Se compara ahora dos lenguajes Java y Ruby, el primero posiblemente con afirmaciones
muy fuertes sobre su productividad y el segundo incluso no muy conocida y para varios
individuos débil y no confiable.
Ruby y Java
Java está maduro, probado y es rápido. Al ir de Java hacia Ruby, se espera que el
tamaño de tu código disminuya considerablemente. También se espera que lleve menos
tiempo el armado de prototipos. Se expone ahora algunos pros y contras tanto de Java
como de Ruby, según lo que expone (MONTORO, 2013):
Java:

El entorno J2EE nunca ha acabado de funcionar bien, ni en rendimiento ni en
disponibilidad

La Comunidad y el soporte de PHP han crecido hasta igualar o superar el de Java,
incluyendo grandes fabricantes como IBM, que presta servicios sobre PHP.

Java se está debilitando. Con la aparición de nuevos lenguajes: Ruby, Python,
Groovy, Scala, entre otros. cada vez se va diluyendo más el uso de Java lo mismo
que pasó con el lenguaje C++ a finales de los noventa.

Java es relativamente complicado. En particular la rama de EJB y Servicios Web
tiene una curva de aprendizaje que crece lentamente.
Ruby:

Ruby es como el lenguaje de programación que a uno siempre le hubiera gustado
diseñar: combina buenas ideas de Perl y Smalltalk, Python, Lisp, Dylany CLU.

Ruby ofrece mejor productividad medida en líneas de código necesarias para
desarrollar una funcionalidad.

Un equipo de programadores bien organizado y motivado puede estar produciendo
aplicaciones Ruby on Rails en menos de dos semanas de formación. Lo que
muestra que Ruby tiene una curva de aprendizaje de crecimiento rápido.

Muchos visionarios de la industria apoyan Ruby, incluyendo al mismísimo James
Duncan Davidson, creador de Tomcat, y David Geary, diseñador de JavaServer
Faces.
76
Por otra parte también se podría comparar el número de líneas que se utiliza en código de
programación por ejemplo para crear el método listar:
Código Java
Código Ruby
Se puede apreciar en este ejemplo simple que Java utiliza varias líneas de código en
comparación con las que utiliza Ruby. El resultado obtenido con Ruby on Rails muestra
que hay un sin fin de maneras de evitar repetir código (DRY - Don't Repeat Yourself).
Se utiliza la arquitectura MVC (Modelo, Vista, Controlador) expuesta en la teoría y se vio
que lo que busca es dividir el trabajo de un aplicación en diferentes puntos: el modelo que
se encarga de los datos, la vista que se encarga de mostrar los datos de una manera más
amigable y el controlador que se encarga de las peticiones y respuestas de información
entre el modelo y la vista para que el usuario pueda verla.
Se ha visto que las gemas son unas de las grandes novedades que presenta Rails y se
pudo ver durante la investigación que existe una comunidad activa desarrollando y
mejorándolas, estas ayudan en el desarrollo de aplicaciones, estas pueden ser tan
eficientes como Scaffold que es capaz de crear con una sola línea de código el modelo, la
vista y el controlador.
Rails cumple con los principios de otro modelo, el modelo REST. Sin querer ponerse muy
técnico, entre varias cosas esto significa que utiliza las acciones CRUD (Create, Read,
Update, Delete) del protocolo HTTP, en código eso se traduce en utilizar POST, GET,
PUT Y DELETE como debe hacerse, y en cuestiones de beneficios eso significa que la
misma URL puede llamar a las distintas acciones que se menciona.
77
Con la utilización de todas las gemas existentes se puede estar menos preocupado por la
programación y más por la visualización y da como resultado páginas más llamativas para
el usuario.
Con Ruby on Rails el desarrollo de aplicaciones se produce en menos tiempo y con gran
flexibilidad pudiendo modificarlos, editarlos o extendiéndolo después de ejecutarlo, lo que
conduce a la reducción de costos y una mejor rendimiento en la inversión.
Se puede trabajar en una base de datos y luego con toda la facilidad cambiar de gestor
sin que esto sea un dolor de cabeza para el desarrollador, en Rails hay un concepto que
se llama migraciones que son modificaciones a la base de datos que se guardan en una
archivo de esquema, también se puede revertir estas modificaciones así mismo sin que
esto presente gran dificultad.
78
5. CONCLUSIONES
Al finalizar el presente trabajo se concluye lo siguiente:

Conocer la tecnología Ruby on Rails permite establecer con claridad la diferencia
de desarrollar aplicaciones web con el lenguaje presentado y otros lenguajes como
Java, PHP entre otros.

Rails da la libertad de centrarse en otros aspectos, mas no sobre el lenguaje en sí,
pues los generadores crean código robusto, seguro y de fácil entendimiento.

El estudio de Ruby on Rails abre otro camino para el desarrollo de aplicaciones
web, permitiendo que no se estanque en lenguajes de programación tradicionales.
La exploración de nuevas herramientas es fundamental para formar un potencial
desarrollador.

Este proyecto permite determinar con claridad las prestaciones que brinda una
aplicación como producto final, y debido a esto se considera los factores más
importantes: El patrón MVC, reutilización DRY (Don't Repeat Yourself), la
seguridad de aplicación, madurez del producto.

Algunos frameworks, como los de Java para aplicaciones web necesitan hacer una
múltiple cantidad de configuraciones en archivos y cada una con muchos ajustes,
Rails hace esto más fácil asumiendo convenciones sobre configuración que es un
paradigma de programación que busca minimizar el número de decisiones que un
desarrollador necesita hacer, ganando así en simplicidad pero no perdiendo
flexibilidad por ello.

La seguridad de la aplicación demanda una correcta utilización de factores que
determinan un correcto cuidado de la información tanto al momento de la
autenticación de usuarios como al manejo de la aplicación en sí. Ruby on Rails
demuestra la eficiencia en la seguridad de las aplicaciones gracias a la utilización
de su gema Device, además tiene grandes características de seguridad
incorporadas, lo que permite que las aplicaciones web desarrolladas en Rails no
se vean afectado por los ataques de inyección SQL.
79

La elaboración de la aplicación web permite entender el manejo de la información
estática y dinámica de un sitio, que es fácilmente administrado por el uso de la
base de datos o por las páginas HTML.

Ruby on Rails es una herramienta robusta, flexible y de fácil manejo, con la cual se
verifica que el desarrollo de las aplicaciones no necesita mucho tiempo. Su sintaxis
es sencilla, la codificación a largo plazo para cualquier aplicación o página es más
fácil de mantener.

Ruby on Rails más que un framework es el proyecto central de una comunidad
gigante que produce de manera constante librerías (gemas) para simplificar las
tareas de crear complejas aplicaciones web.

Rails está diseñado con las mejores prácticas, por lo que de manera natural lleva a
escribir código increíble. Hay gemas para casi cualquier cosa que se necesita en
una aplicación web.

Utilizando Rails se puede construir aplicaciones web de lo que se tenga en mente,
sólo hay que darle un vistazo a algunos grandes que construyeron sus sitios con
Rails: BaseCamp, Airbnb, Github, Hulu, Indiegogo, KickStarter, Pixlr, Shopify,
Square, Zendesk entre otros. Hay más de 200,000 sitios web usando Rails.

Muchas empresas llamativas que se conoce usan Ruby, como lo son: Amazon,
BBC, Cisco, CNET, IBM, JP Morgan, NASA, Yahoo.

En pocas horas es posible construir aplicaciones web y dejarlas online
funcionando. Para que se tenga una idea, la primera versión de Twitter la hicieron
en un día usando Ruby on Rails.

Los beneficios de Rails son muchos, y probablemente faltó mencionar el manejo
sencillo de relaciones en Rails, el ActiveRecord, migraciones más a detalle, la
configuración de los Routers, que con la experiencia del trabajo, son otras razones
por las cuales programar en Rails es una buena opción.

Ni Java ni PHP desaparecerá en un corto tiempo, ni es óptimo para un
desarrollador quedarse utilizando los mismos lenguajes toda una vida.

Como reflexión final, se puede expresar que lo mejor de conocer varios
frameworks es saber que no existe uno que sea la solución a todos los problemas
sino que cada uno fue desarrollado con objetivos diferentes y es necesario ver cuál
de todos se alinea mejor con los objetivos de nuestro proyecto evaluando ventajas
y desventajas de cada uno.
80
6. RECOMENDACIONES

El objetivo del presente proyecto no ha sido solo el de explicar el contexto de Ruby
on Rails, si no también transmitir nuevos conceptos y tecnologías que en la
actualidad están en pleno desarrollo y en adopción por diversas empresas. Por lo
tanto con este trabajo, se recomienda incentivar a docentes y estudiantes la
investigación y descubrimiento de nuevas herramientas con las cuales se logre
estar un grado por encima del resto en lo que a desarrollo de sistemas se refiere.

Es importante que se tenga en mente que para ser un experto en Rails va a
conllevar varias horas, así como desarrollar cualquier otra habilidad. Por lo que lo
mejor es que se comience utilizando el presente documento tomando en cuenta
que es una guía introductoria.

Para conocer más sobre los conceptos en Rails es recomendable aprender los
conceptos de Ruby que se lo puede empezar por la propia página de Ruby y visitar
Tryruby (http://tryruby.org/) donde se puede probar la sintaxis de Ruby y ver cómo
funciona.

Como desarrollador de aplicaciones web se va a necesitar saber JavaScript,
HTML, CSS. No es un pre-requisito para aprender Rails pero si es una habilidad
que se necesita aprender. A medida que se sumerge más y más en el mundo web
se va a dar cuenta que se necesita saber diferentes tecnologías. Afortunadamente,
a medida que se gana experiencia aprender un nuevo lenguaje y framework se
hace más fácil.

Es necesario constantes actualizaciones de conocimiento de los lenguajes de
programación, ya que hoy en día la actualización de los conocimientos es
sumamente importante para el crecimiento de la población dedicada al campo de
la informática.

Los objetivos del análisis se pueden aprovechar en otros ámbitos, como en la
enseñanza en aulas universitarias, ya que al estar siempre acostumbrados a
programar en base a ciertos parámetros generales, y con un grupo de lenguajes
de aplicaciones web, su paradigma de codificación va a estar sujeto a un solo
81
esquema, pero al explorar nuevas herramientas, su manera de solucionar
problemas se expande dándole un abanico más amplio de conocimientos y
posibles respuestas ante necesidades.

Es recomendable conocer las diferentes partes del framework y como trabajar con
ellos. Una de las formas más divertidas es con la que ofrece Rails for zombies
(http://railsforzombies.org/) un sitio que guia a través de una serie de tutoriales y
videos donde se puede ver cómo funciona.

Existen numerosas gemas de Ruby para realizar tareas realmente dispares. Y es
que el número de éstas ha aumentado considerablemente en los últimos años,
proveyendo a los desarrolladores de un gran número de librerías útiles con las que
se facilita el trabajo. Se recomienda ver el Anexo A para ver la configuración de
dos de estas gemas, Devise y kaminari.

Para replicar el ejemplo se debe leer cada una de las secciones completas y luego
replicar línea por línea, sin perder de vista cada uno de los detalles que se
escriben antes y luego de la presencia del código.

Para ver en acción el ejemplo desarrollado que se describe en el proyecto se tiene
que
descargar
el
código
fuente
desde
el
siguiente
link
https://www.dropbox.com/s/38rvext96r35mee/WebAppFinal.rar?dl=0, además se
puede descargar el ejemplo con mejora en estilos desde el siguiente link
https://www.dropbox.com/s/g58yxirys8izhh5/AppWebCEFinal.rar?dl=0,
y
finalmente cargar el proyecto a su instalacion de Rails de la forma que muestra el
Anexo B.
82
BIBLIOGRAFÍA
1. BARZANALLA, R. (2012). Universidad de Murcia. Recuperado el 05 de Enero de
2015,
de
http://www.um.es/docencia/barzana/DIVULGACION/INFORMATICA/Historiadesarrollo-aplicaciones-web.html
2. BEHAR, D. (2008). Metodología de la investigación. Shalom.
3. BURBECK, S. (2015). How to use Model-View-Controller (MVC). Recuperado el 22
de
02
de
2016,
de
How
to
use
Model-View-Controller
(MVC):
http://web.archive.org/web/20150518095937/http://stwww.cs.illinois.edu/users/smarch/st-docs/mvc.html
4. DE LA TORRE VILLAR, E., & NAVARRO DE ANDA, R. (1990). Metodologìa de la
Investigación. Mexico: Mcgraw-Hill.
5. DEV,
V.,
&
Noria,
X.
(s.f.).
RailsGuide.
Obtenido
de
RailsGuide:
http://guides.rubyonrails.org/index.html
6. HEINEMEIER, D. (2006). Ruby on Rails. Recuperado el 23 de 02 de 2016, de
Ruby
on
Rails:
http://web.archive.org/web/20131220211233/http://dev.mysql.com/techresources/interviews/david-heinemeier-hansson-rails.html
7. LIBROSWEB.ES. (2006-2016). Intriducción a Ruby on Rails. Recuperado el 05 de
Enero
de
2016,
de
http://librosweb.es/libro/introduccion_rails/capitulo_2.html
8. MARK, L. (2010). Learning Python, Fourth edition. O'Reilly.
83
LibrosWeb:
9. MONTORO, S. (2013). Como selecionar una plataforma de desarrolo para un
proyecto web. Recuperado el 07 de Enero de 2016, de La pastilla Roja:
http://lapastillaroja.net/2013/10/como-seleccionar-plataforma-tecnologica/
10. ORTIZ, F., & GARCIA, M. d. (2005). Metodología de la Investigación. Mexico:
Limusa.
11. PUENTE, R. (2014). Ruby-Gemas, que son y para qué sirven. Recuperado el 06
de
Enero
de
2016,
de
Ruby-Gemas,
que
son
y
para
qué
sirven:
http://blog.rodrigopuente.com/ruby-gemas-que-son-y-para-que-sirven/
12. RODRIGUEZ U, M. L. (2013). Acerca de la Investigación Bibliográfica y
documental. Recuperado el 04 de Enero de 2016, de Guia de Tesis:
https://guiadetesis.wordpress.com/2013/08/19/acerca-de-la-investigacionbibliografica-y-documental/
13. RUBY, C. (s.f.). Acerca de Ruby. Recuperado el 05 de Enero de 2016, de Ruby:
https://www.ruby-lang.org/es/about/
14. WIKIPEDIA. (2015). Aplicaciones Informaticas. Recuperado el 09 de Enero de
2016,
de
Wikipedia:
https://es.wikipedia.org/wiki/Aplicaci%C3%B3n_inform%C3%A1tica
15. WIKIPEDIA. (2016). Lenguages de Programación. Recuperado el 09 de Enero de
2016,
de
Wikipedia:
https://es.wikipedia.org/wiki/Lenguaje_de_programaci%C3%B3n
16. WIKIPEDIA. (2016). Ruby on Rails. Recuperado el 27 de 02 de 2016, de Ruby on
Rails: https://es.wikipedia.org/wiki/Ruby_on_Rails
84
ANEXOS
ANEXOS
85
ANEXO A
Device
Configuración de Vistas
Device ayuda a desarrollar rápidamente una aplicación que utiliza autenticación. Sin
embargo, no se encuentran los archivos cuando se necesita para personalizarlo.
Device es un motor, todas las vistas son empaquetadas dentro de la gema, pero luego de
algún tiempo es posible que se desee cambiarlas. Si es el caso, sólo se tiene que invocar
el siguiente generador, y se copian todas las vistas a la aplicación:
C:\Sites\AppWeb>rails g devise:views
Si se desea generar sólo algunas de las vistas, como los módulos de registrar y confirmar,
puede pasar una lista de módulos para el generador con la bandera -v.
C:\Sites\AppWeb>rails generate devise:views -v registrations
confirmations
Configuración de Controladores
Si la personalización a nivel de vistas no es suficiente, se puede personalizar cada
controlador siguiendo estos pasos:
Crear sus controladores personalizados utilizando el generador que requiere un scope:
C:\Sites\AppWeb>rails generate devise:controllers [scope]
Si
se
especifica
Users
como
scope,
los
controladores
serán
creados
en
app/controllers/usuarios/.
Decirle al router para que utilice el controlador, por ejemplo el de sesión:
C:\Sites\AppWeb>devise_for :usuarios, controllers: {
sessions:"usuarios/sessions" }
Copiar las vistas desde devise/sessions to users/sessions. Dado que el
controlador se ha cambiado, no va a utilizar las vistas predeterminadas que se encuentran
86
en devise/sessions. Por último, cambiar o ampliar las acciones de los controladores
deseados.
Kaminari Personalización de la paginación
Kaminari incluye un generador de plantilla práctica para editar el paginador. Ejecutar el
generador:
C:\Sites\AppWeb>rails g kaminari:views default
luego editar los parciales de su aplicación en el directorio app/views/kaminari/.
Idioma de Etiquetas
Las etiquetas por defecto se almacenan el interior de las gemas. Se puede cambiar el
valor de las etiquetas para la aplicación adicionando líneas de código en el archivo
en.yml que se encuentra en el directorio /config/locales/. En el caso de Devise
crea un archivo devise.en.yml en el mismo directorio que se lo puede modificar.
También en las aplicaciones que se encuentran para descargar se pude ver más
configuraciones de este archivo. Como ejemplo se muestra la configuración de paginación
de kaminari en el archivo en.yml:
en:
hello: "Hola Mundo"
views:
pagination:
first: "« Primero"
last: "Ultimo »"
previous: "‹ Anterior"
next: "Siguiente ›"
truncate: "..."
helpers:
page_entries_info:
one_page:
display_entries:
zero: " %{entry_name} No Encontrado"
one: "Muestra <b>1</b> %{entry_name}"
other: "Muestra <b>Todos los %{count}</b> %{entry_name}"
more_pages:
display_entries: "<b>  %{first}  al
 %{last}</b>  de   <b>%{total}</b> "
87
ANEXO B
Cargar aplicación al servidor
Para cargar la aplicación que se dejó en los link de la sección recomendaciones al
servidor de Rails, se tiene instalar Rails si aún no se lo ha hecho como se muestra en el
punto número 3 de este documento y luego descomprimir el archivo .rar y copiar la
carpeta resultante al directorio C:\Sites\. Luego mediante el terminal ingresar a la carpeta
del proyecto con el comando cd nombreProyecto, así.
C:\Sites\>cd AppWeb
Se verifica la instalacion de gemas con los comandos bundle install y bundle
update respectivamente, así
C:\Sites\AppWeb> bundle install
C:\Sites\AppWeb> bundle update
Se crea la base de datos desde la aplicación, tomar en cuenta que se debe cambiar los
datos del archivo /config/database.yml con los de su base de datos, y luego
ejecutar:
C:\Sites\AppWeb>rake db:create
Se carga el esquema de los modelos, con el comando:
C:\Sites\AppWeb>rake db:schema:load
Finalmente se inicia el servidor
C:\Sites\AppWeb>rails s
88
ANEXO C
Configurar Correo Electrónico
Para establecer el sistema de correo electrónico para la aplicación con devise y que se
pueda enviar correos electrónicos, para restablecer contraseñas. Se debe editar varios
archivos.
Primero
abrir
el
archivo
devise.rb
que
se
encuentra
en
el
directorio
/config/initializer y realizar el cambio de:
config.mailer_sender = '[email protected]'
por el email que se quiere que envié los correos:
config.mailer_sender = '[email protected]'
además se debe verificar que la siguiente línea este descomentada.
config.secret_key =
'c7167fda544135cdc6eaa8124d9ea3944dbeb29274c79b8e045103a18e3ef5e5b
b1a849ae9873b1ae158560aeb8666d03d301b2290561abac11db00e89351e2d'
Los
archivos
que
se
pueden
editar
se
encuentran
en
el
directorio
/config/environments/, este contiene los archivos para configurar los entornos de
pruebas, desarrollo o producción, en este caso se configura el archivo de desarrollo
development.rb, agregando las líneas de código se configura el envió de email con
una cuenta de outlook:
config.action_mailer.default_url_options = { :host =>
'localhost:3000' }
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
address: "smtp.live.com",
port: 587,
authentication: "plain",
enable_starttls_auto: true,
user_name: "[email protected]",
password: "tupassword"
}
89
Ahora ya se puede restablecer contraseñas desde la autenticación de device, esta
configuración se debe realizar al entorno que se desea.
Para poder cambiar la configuración con otros servidores de email se muestra
características de algunos de estos:
YAHOO:
•
Servidor de correo
•
Servidor de correo
•
Port: 587
GMAIL:
•
Servidor de correo
•
Servidor de correo
•
Port: 587
HOTMAIL y OUTLOOK:
•
Servidor de correo
•
Servidor de correo
•
Port: 587
entrante (POP3): pop.correo.yahoo.es
saliente (SMTP): smtp.correo.yahoo.es
entrante (POP3): pop.gmail.com
saliente (SMTP): smtp.gmail.com
entrante (POP3): pop3.live.com
saliente (SMTP): smtp.live.com
90
ANEXO D
Carrito Básico de Compras
En este punto se va a manejar sesiones y poder crear un carrito básico de compras, para
ello primero se añade al método index() del controlador de home la lista de los
productos que se tiene de la siguiente manera:
class HomeController < ApplicationController
def index
@productos = Producto.order(:nombre).page(params[:page]).per(10)
end
end
se los visualiza añadiendo a la vista index.html.erb de home el siguiente código:
<div class="row center-xs">
<div class="col-sm-8"><h1>Lista de Productos</h1>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>Nombre</th>
<th>Descripcion</th>
<th>Precio</th>
<th>Fecha</th>
<th>Tipo producto</th>
<th>Fabricante</th>
<th>Imagen</th>
<th colspan="3"></th>
</tr>
</thead>
<tbody>
<% @productos.each do |producto| %>
<tr>
<td><%= producto.nombre %></td>
<td><%= simple_format(h(producto.descripcion)) %></td>
<td><%= number_to_currency(producto.precio) %></td>
<td><%= producto.fecha %></td>
<td><%= producto.tipo_producto.nombre %></td>
<td><%= producto.fabricante.nombreFab %></td>
<td><%= image_tag producto.urlImagen.url() %></td>
</tr>
<% end %>
</tbody>
</table>
<%= paginate @productos %>
</div></div>
91
Figura 31 Producto Home
A medida que navegan por la aplicación, se espera seleccionar los productos a comprar.
La convención es que cada elemento seleccionado será añadido a un carrito de compra
virtual. Esto significa que la aplicación tendrá que mantener un registro de todos los
productos añadidos al carrito. Para realizarlo, se va a crear un carrito en la base de datos
y almacenar su identificador único, cart.id, en la sesión. Cada vez que llega una
petición, se puede recuperar la identidad de la sesión y utilizarlo para encontrar el carrito
en la base de datos. Para ello crear el modelo Cart.
C:\Sites\AppWeb>rails generate scaffold Cart
luego migrarlo como se lo ha estado haciendo
C:\Sites\AppWeb>rake db:migrate
Rails hace que se mire a las sesiones presentes como un hash para el controlador, por lo
que se va a almacenar el ID del carrito en la sesión mediante la indexación con el símbolo
:cart_id. Para esto se crea el archivo current_cart.rb en el directorio
/app/controllers/concerns/ con el siguiente contenido.
92
module CurrentCart extend ActiveSupport::Concern
private
def set_cart
@cart = Cart.find(session[:cart_id])
rescue ActiveRecord::RecordNotFound
@cart = Cart.create
session[:cart_id] = @cart.id
end
end
El método set_cart() inicia por obtener el :cart_id del objeto de sesión y luego
intenta encontrar un carrito correspondiente a este ID. Si no se encuentra un registro,
entonces este método va a proceder a crear un carrito nuevo, almacena el ID del carrito
creado en la sesión, y luego devuelve el carrito nuevo.
Un carrito contiene un conjunto de productos. Ahora generar el modelo para crear la
conexión entre el carrito y los productos de la siguiente forma.
C:\Sites\AppWeb>rails generate scaffold LineItem
producto:references cart:belongs_to
luego migrarlo como se lo ha estado haciendo rake db:migrate
La base de datos tiene ahora un lugar para almacenar las referencias entre artículos de
sesión, carritos y productos. Si se observa en la definición de la clase generada
LineItem, se puede ver las definiciones de estas relaciones.
class LineItem < ActiveRecord::Base
belongs_to :product
belongs_to :cart
end
Para ser capaces de atravesar estas relaciones en ambas direcciones, se tiene que
añadir algunas declaraciones de nuestros archivos de modelos que especifican sus
relaciones inversas. Primero se lo hará para el modelo Cart.
class Cart < ActiveRecord::Base
has_many :line_items, dependent: :destroy
end
La parte de la directiva has_many: line_items es bastante explica por sí mismo: un
carrito (potencialmente) tiene muchos elementos asociados con line_items. Estos
93
están vinculados al carrito porque cada line_items contiene una referencia a la ID del
carrito. La parte dependent: :destroy indica que la existencia de un line_items
depende de la existencia del carrito. Si se destruye un carrito, eliminarlo de la base de
datos, rails también destruye los line_items que se asocian con ese carrito.
Ahora, se tiene que añadir una directiva has_many al modelo del Producto.
has_many :line_items
Después de todo, si se tiene varios carritos, cada producto puede tener varios line items
que hacen referencia a ellos. Esta vez, se va a hacer uso de un código de validación para
impedir remover los productos que son referenciados por los line items. En el mismo
modelo de Producto aumentar el callback y el método siguiente.
before_destroy :ensure_not_referenced_by_any_line_item
#.......
private
# asegura de que no hay ninguna line_item que hacen referencia
a un producto
def ensure_not_referenced_by_any_line_item
if line_items.empty?
return true
else
errors.add(:base, 'Line Items presente')
return false
end
end
Aquí se declara que un Producto tiene muchos Line Items y se define un método
hook llamado ensure_not_referenced_by_any_line_item(). Un método hook es
un método que Rails llama automáticamente en un punto dado en la vida de un objeto. En
este caso, se llama al método antes que Rails intente destruir una fila en la base de datos.
Si el método hook devuelve false, la fila no será destruida.
Es el momento de colocar un botón “Añadir al Carrito” para cada producto. No hay
necesidad de crear un nuevo controlador o incluso una nueva acción. Lo que se está
creando ciertamente no es un carro o incluso un producto. Se está creando un LineItem.
En total, la línea que hay que añadir a la vista index.html.erb del modelo home se ve
así:
94
<td><%= button_to 'Añadir al carrito',
line_items_path(producto_id: producto) %></td>
Quedando de la siguiente forma
<div class="row center-xs">
<div class="col-sm-8">
<h1>Lista de Productos</h1>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>Nombre</th>
<th>Descripcion</th>
<th>Precio</th>
<th>Fecha</th>
<th>Tipo producto</th>
<th>Fabricante</th>
<th>Imagen</th>
<th colspan="3"></th>
</tr>
</thead>
<tbody>
<% @productos.each do |producto| %>
<tr>
<td><%= producto.nombre %></td>
<td><%= simple_format(h(producto.descripcion))
%></td>
<td><%= number_to_currency(producto.precio) %></td>
<td><%= producto.fecha %></td>
<td><%= producto.tipo_producto.nombre %></td>
<td><%= producto.fabricante.nombreFab %></td>
<td><%= image_tag producto.urlImagen.url() %></td>
<td><%= button_to 'Añadir al carrito',
line_items_path(producto_id: producto) %></td>
</tr>
<% end %>
</tbody>
</table>
<%= paginate @productos %>
</div>
</div>
95
Figura 32 Añadir Carrito
Ahora se modificar el controlador LineItemsController para encontrar el carrito para la
sesión actual (la creación de uno si no hay uno ya), añadir el producto seleccionado para
ese carrito, y mostrar el contenido del carrito.
Se incluye el módulo CurrentCart que se implementó para encontrar (o crear) un carrito
en
la
sesión.
Para
esto
se
aumenta
las
líneas
en
el
controlador
app/controllers/line_items_controller.er
class LineItemsController < ApplicationController
include CurrentCart
before_action :set_cart, only: [:create]
before_action :set_line_item, only: [:show, :edit, :update,
:destroy]
# GET /line_items
……….
end
Se Incluyó el módulo CurrentCart y declara que el método set_cart() es llamado
antes de la acción create().
96
Asociar un contador con cada producto en nuestro carrito va a requerir modificar el
modelo line_items. Utilizando las migraciones se va aumentar un campo cantidad así:
C:\Sites\AppWeb>rails generate migration
add_cantidad_to_line_items cantidad:integer
Antes de migrar se va a modificar el archivo para aumentar el valor default: 1 a la
migración quedando de la siguiente manera
class AddCantidadToLineItems < ActiveRecord::Migration
def change
add_column :line_items, :cantidad, :integer, default: 1
end
end
Una vez completado, se corre la migración con rake db:migrate
Ahora se necesita un método inteligente en nuestro carrito
add_product(), que
comprueba si en los line_items ya incluye el producto que se está añadiendo; Si lo
hace, se aumenta en la cantidad, y si no lo hace, se construye un nuevo Line Item.
Esto método se lo crea en el modelo Cart, observándose de la siguiente manera:
class Cart < ActiveRecord::Base
has_many :line_items, dependent: :destroy
def add_product(producto_id)
current_item = line_items.find_by(producto_id: producto_id)
if current_item
current_item.cantidad += 1
else
current_item = line_items.build(producto_id: producto_id)
end
current_item
end
end
El método find_by() es una versión simplificada del método where(). En lugar de
devolver un conjunto de resultados, se devuelve un Line Item existente o nulo.
También se tiene que modificar el controlador LineItem para utilizarlo, modificar el
método create() del controlador así:
97
def create
producto = Producto.find(params[:producto_id])
@line_item = @cart.add_product(producto.id)
respond_to do |format|
if @line_item.save
format.html { redirect_to @line_item.cart, notice:
'Producto Añadido al Carrito' }
format.json { render action: 'show', status: :created,
location: @line_item }
else
format.html { render action: 'new' }
format.json { render json: @line_item.errors, status:
:unprocessable_entity }
end
end
end
Lo que es probable que se ve es una mezcla de productos individuales enumerados por
separado y un solo producto que aparece con cantidad de dos. Esto se debe a que se ha
añadido una cantidad de una de las columnas existentes en lugar de colapsar varias filas
cuando sea posible. Para eso se usara una migración.
C:\Sites\AppWeb>rails generate migration combinar_items_en_carrito
En esta ocasión, rails no puede inferir lo que se está tratando de hacer, por lo que no se
puede apoyarse en la método generado change(). Lo que se hace en su lugar es
reemplazar este método con un método separador up(). Esto es fácilmente el código
más extenso que se ha visto hasta ahora.
Empezar por la iteración en cada carrito.
• Para cada carrito, se obtiene una suma de los campos de cantidad para cada uno de los
elementos asociados a este carrito, se agrupa por producto_id. Las sumas resultantes
serán una lista de pares ordenados de producto_ids y cantidad.
• Se Itera sobre estas sumas, extrayendo el producto_id y la cantidad de cada uno.
• En los casos en que la cantidad es mayor que uno, se va a eliminar todos los line
items individuales asociados a este carrito y el producto y reemplazarlo con un único
line item con la cantidad correcta.
98
Para esto se modifica la migración así:
class CombinarItemsEnCarrito < ActiveRecord::Migration
def up
# Sustituye varios items para un solo producto en un carrito
con un solo item
Cart.all.each do |cart|
# cuenta el número de cada producto en el carrito
sums = cart.line_items.group(:producto_id).sum(:cantidad)
sums.each do |producto_id, cantidad|
if cantidad > 1
# elimina elementos individuales
cart.line_items.where(producto_id:
producto_id).delete_all
# sustituye por un solo elemento
item = cart.line_items.build(producto_id: producto_id)
item.cantidad = cantidad
item.save!
end
end
end
end
end
Tenga en cuenta la facilidad y elegancia que Rails le permite expresar este algoritmo. Con
este código en su lugar, se aplica la migración al igual que cualquier otra migración.
C:\Sites\AppWeb>rake db:migrate
Si el carro no se puede encontrar, Active Record lanza una excepción RecordNotFound,
que claramente se tiene que manejar. Surge la pregunta ¿cómo?
Para esto se va a volver a mostrar la página index de home junto con un breve mensaje
(algo como "carrito Inválido") para que pueda seguir utilizando la aplicación. Rails
tiene una forma conveniente de hacer frente a los errores y los informes de errores. Se
define una estructura llamada un flash. Normalmente, el flash se utiliza para recoger los
mensajes de error. Armado con estos antecedentes acerca de los datos de flash, ahora se
puede crear un método invalid_cart () que informe sobre el problema. Se aumenta
lo siguiente rescue_from y el método privado invalid_cart() en el controlador de
Carts asi.
99
class CartsController < ApplicationController
before_action :set_cart, only: [:show, :edit, :update, :destroy]
rescue_from ActiveRecord::RecordNotFound, with: :invalid_cart
# GET /carts
…….
Private
…..
def invalid_cart
logger.error " Intenta acceder al carrito no válido
#{params[:id]}"
redirect_to root_path, notice: ' Carrito Invalid'
end
end
Se debe de preocupar por cada interfaz posible porque las crackers maliciosos pueden
conseguir por debajo de HTML que se proporciona y tratar de proporcionar parámetros
adicionales. Los Carritos inválidos no son nuestro mayor problema aquí; también se
quiere impedir el acceso a los carritos de otras personas. Como siempre, los
controladores son la primera línea de defensa. Se va a retire el parámetro :cart_id de la
lista de parámetros que están permitidos en el controlador de Line Item, quedando de
la siguiente manera.
def line_item_params
params.require(:line_item).permit(:producto_id)
end
Ahora en el controlador de Cart, se va a modificar el método destroy() para garantizar
que el usuario está eliminando su propio carrito y para quitar el carrito de la sesión antes
de redirigir a la página de inicio con un mensaje de notificación.
def destroy
@cart.destroy if @cart.id == session[:cart_id]
session[:cart_id] = nil
respond_to do |format|
format.html { redirect_to root_path, notice: ' Su carrito
está vacío ' }
format.json { head :no_content }
end
end
y también se modifica el método index() del mismo archivo quedando así:
100
def index
@carts = Cart.all
respond_to do |format|
format.html {redirect_to root_path}
end
end
Para finalizar y poder ver el carrito en acción se tiene que editar la vista show del modelo
Carts colocando el siguiente código
<% if notice %>
<p id="notice"><%= notice %></p>
<% end %>
<h2>Mis Compras</h2>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th></th>
<th>Cantidad</th>
<th>Producto</th>
<th>Precio</th>
<th>Total</th>
</tr>
</thead>
<tbody>
<% @cart.line_items.each do |item| %>
<tr>
<td><%= image_tag item.producto.urlImagen.url() %></td>
<td><%= item.cantidad %>×</td>
<td><%= item.producto.nombre %></td>
<td class="item_price"><%=
number_to_currency(item.producto.precio) %></td>
<% total = item.cantidad*item.producto.precio %>
<td><%= number_to_currency(total) %></td>
</tr>
<% end %>
</tbody>
</table>
<%= button_to 'Eliminar Carrito', @cart, method: :delete,data: {
confirm: 'Estás Seguro?' } %>
101
Figura 33 Mis compras
102
ANEXO E
Diagrama de flujo
El presente punto de diseño de la aplicación web nace el entendimiento detallado de los
requisitos y requerimientos que se desea. Este documento organiza la información
obtenida y la analiza para conformar los diagramas que servirá al desarrollo.
Análisis y Especificación de requerimientos de software
Requerimientos funcionales y no funcionales del sistema
Los requerimientos funcionales sirven para definir lo que el sistema será capaz de hacer.
En base al análisis realizado se han identificado los siguientes requerimientos:
Requerimientos funcionales

El sistema permitirá la gestión (crear, modificar, deshabilitar) de Tipos Productos.

El sistema permitirá la gestión (crear, modificar, deshabilitar) de Fabricantes.

El sistema permitirá la gestión (crear, modificar, deshabilitar) de Proveedores.

El sistema permitirá la gestión (crear, modificar, deshabilitar) de Productos.
Requerimientos No Funcionales

El sistema permitirá gestionar los usuarios (crear, modificar, deshabilitar).

El sistema permitirá la autenticación de los usuarios por usuario y contraseña.

El sistema permitirá cambiar la contraseña al usuario.

El sistema permitirá la creación de un carrito de compras.

El sistema debe ser web.

El sistema será soportado en navegadores Firefox, Safari, Opera, Chrome y/o
Explorer.
Modelo de Dominio
La elaboración del modelo de dominio consiste en la construcción del glosario del
proyecto, o un diccionario de términos que serán usados en el proyecto. Este modelo es
la fuente inicial sobre la cual se describirán los casos de uso mostrando gráficamente
103
como se relacionan los diferentes objetos identificados durante la etapa de análisis de
requerimientos para el sistema.
Para el desarrollo del sistema se ha elaborado el modelo de dominio representado en la
Figura 13 de la sección 3. Este modelo de dominio contiene los objetos básicos que han
sido identificados. Los objetos más representativos que se han identificado son Tipo de
Producto, Fabricante, Producto y Proveedor.
Casos de Uso
Para la elaboración e identificación de los diagramas de casos de uso se ha partido del
análisis de los requisitos del sistema. Se ha identificado claramente al actor (Súper
usuario), el cuales nos permitirán analizar de forma distribuida el Casos de Uso para este
Actor.
Casos de uso actor Súper Usuario
El Súper usuario es el Administrador del Sistema que tendrá acceso a cada parte del
sistema. El diagrama de casos de uso se lo puede ver en la Figura 1.2.
Figura 34 Super Usuario
Descripción de Casos de Uso
A continuación se describirán los casos de uso, además se realizará el diagrama de flujo
correspondiente.
104
Figura 35 Un diagrama de flujo a nivel de contexto
105
Nombre Caso de Uso
Descripción
Actor
Precondición
Postcondición
Flujos
principal
alternativo(s)
Ingresar Al Sistema
El usuario podrá ingresar al sistema.
Usuarios
Usuario debe estar registrado y poseer un nombre de usuario,
contraseña
Usuario accede al sistema.
y
Nota
106
Nombre Caso de Uso
Descripción
Actor
Precondición
Postcondición
Flujos
principal
y
alternativo(s)
Registrar Usuario
El usuario puede registrar su cuenta en sistema.
Súper Usuario
El usuario del sistema desea registrarse.
Se crea una cuenta de usuario
Nota
107
Nombre Caso de Uso
Descripción
Actor
Precondición
Postcondición
Flujos
principal
y
alternativo(s)
Actualizar Mi Información
El usuario podrá actualizar su información.
Súper Usuario
Usuario ha iniciado sesión
Usuario ha actualizado su información.
Nota
108
Nombre Caso de Uso
Descripción
Actor
Precondición
Postcondición
Flujos
principal
alternativo(s)
Registrar Modelo (Tipo, Fabricante, Proveedor y Producto)
El súper usuario del sistema se encargara de crear los modelos del
sistema.
Súper Usuario
Usuario ha iniciado sesión y existen modelos por crear.
Se crea un modelo
y
Nota
109
Nombre Caso de Uso
Descripción
Actor
Precondición
Postcondición
Flujos
principal
alternativo(s)
Consultar Modelo (Tipo, Fabricante, Proveedor y Producto)
El usuario puede consultar los modelos y visualizar información de
cada uno de ellos.
Súper Usuario
Usuario ha iniciado sesión.
El sistema despliega información del modelo que se ha
seleccionado.
y
Nota
110
Nombre Caso de Uso
Descripción
Actor
Precondición
Postcondición
Flujos
principal
alternativo(s)
Actualizar Modelo (Tipo, Fabricante, Proveedor y Producto)
El usuario podrá actualizar la información de un modelo
seleccionado.
Súper Usuario
Usuario ha iniciado sesión.
Usuario habrá modificado los datos de un modelo registrado.
y
Nota
111
Descargar