Mostrando entradas con la etiqueta Backend. Mostrar todas las entradas
Mostrando entradas con la etiqueta Backend. Mostrar todas las entradas

viernes, 23 de septiembre de 2016

Relación 1 a muchos (Categorias/Clasificación de Artículos)

Se pretende clasificar los artículos creados con un scaffold en sus diferentes categorías. Un Artículo puede pertenecer a una sola Categoría, y una Categoría puede tener muchos Artículos, es por eso que nuestra relación es de 1 a muchos.

Hay 2 métodos para lograrlo, uno es la manera sencilla, creada a partir de las relaciones, la segunda, es un poco más compleja, utilizando los maps para ir almacenando las opciones al momento de desplegar las categorías.



1er MÉTODO


1.- Generar el scaffold de Category y correr la migración. Tendrá como único campo name para poder asignarle un nombre a la categoría

     rails g scaffold Category name 

     rake db:migrate



2.- Crear la relación. En caso de que no existiera la tabla Articles, se podría generar un scaffold y usar un category:references para que este, creara la relación y el campo que guardaría el ID de las categorías. En este caso, la tabla ya está creada, por lo tanto, generaremos el campo de forma manual, creando una migración para añadir este nuevo campo:

     rails generate migration add_category_id_to_articles category:references


Este comando generará automáticamente la migración que necesitamos, añadiendo una referencia en la tabla Artícles de la tabla Categories, con un campo llamado category_id, haciéndolo llave foránea y creando un índice:

(clic para agrandar)
 Después, solo será cuestión de correr la migración con rake db:migrate



3.- En la carpeta de modelos, modificaremos el recién creado (category.rb) y el de los artículos (article.rb). En el de las categorías, indicaremos como has_many los artículos debido a que una categoría puede estar presente en muchos artículos, y validaremos que el campo name sea único y no pueda quedar en blanco:


  has_many :articles
validates :name, uniqueness: {message: "Ya existe una categoría con este nombre"},
        presence: { message: "El nombre de la categoría no puede quedar vacío"}


(clic para agrandar)

Y en el de los modelo de artículos, pondremos como belongs_to a categorias, ya que se pretende, que un artículo solo pueda tener 1 categoria, al igual que validaremos que dicho campo sea llenado:

  belongs_to :category

(clic para agrandar)

**Cuando se usa has_many la referencia es en plural y cuando se usa belongs_to debe ir en singular




4.- Iremos al controlador articles_controller y dentro de la función new declararemos la variable que contendrá todas las categorías para que sean accesibles por este método:

@categories = Category.all

(clic para agrandar)



5.- Ahora, iremos a la vista del formulario de nuestros artículos, app/view/articles/ y reemplazaremos el campo que hace mención al category_id (en caso de haberse agregado) y se incluirá un collection_select el cual nos creará una lista desplegable con todas las categorías que hayamos creado. Primero se hace mención al modelo, después el campo y en seguida la variable que se declaró anteriormente, sustituyendo el ID por el nombre de la categoría y agregando un prompt que servirá como opción por defecto cuando aún no se ha seleccionado nada.


= collection_select(:article, :category_id, @categories, :id, :name, :prompt => "Seleccione Uno")

(clic para agrandar)



6.- De la misma manera en que se hizo en el punto 4, será necesario declarar la variable en el método edit para poder visualizar las categorías cuando se esté en el formulario de edición:

(clic para agrandar)


*** No olvidar agregar el campo de category_id a la lista de parámetros fuertes

Aplicando ejemplos:

Menú superior basado en categorías:


1.- En el controlador application_controller.rb crearemos un before_action debido a que necesitamos pasar información a todas las vistas (que por ende, el menú deberá integrarse en views/layouts/application.html.erb ya que esta vista es la que cargara en todas las demás). Así que nuestro before_action llama al método set_categories que definiremos, y este método recoge todas las categorías:


  before_action :set_categories

  private

  def set_categories
   @categoriesmenu = Category.all
  end


(clic para agrandar)



2.- Ahora se puede añadir la navegación en cualquier parte del proyecto accediendo a los datos de @categoriesmenu. En este caso, se crea un menú lateral con una lista, a quien además, se le añade una clase dinámica que se irá autoincrementando para que coincida con algunas clases que definí en CSS. El método para poder imprimir las categorías será con un método each recorriendo @categoriesmenu, y para la clase dinámica simplemente un contador, donde =link_to categoria.name, categoria estaría imprimiendo el nombre(name) de la categoría y funcionaría como enlace hacia la propia categoría, y {:class => "ret#{i+=1}"} sería una atributo que estaríamos pasando por haml (sí, el HTML se encuentra escrito en HAML) para añadir la clase ret concatenando la variable i (antes definida) sumándole 1:



%ul.list-group#menu-prin
     %li.list-group-item.animated.fadeInLeft.ret3=link_to "Inicio", root_path
     -i = 4
     -@categories.each do |categoria|
          %li.list-group-item.animated.fadeInLeft{:class => "ret#{i+=1}"}
               =link_to categoria.name, categoria


(clic para agrandar)

De esta manera, se ha generado nuestro menú lateral, usando las categorías que se encuentran en nuestra tabla Categories.








Relación 1 a muchos (Categorias/Clasificación de Artículos) (MAPS)

2do MÉTODO. MAPS 

Los primeros 3 pasos del primer ejemplo serán los mismos, así que se seguirá con el punto 4 el cuál cambiará para este método:


4.- Mandando las categorías hacia los formularios. Ahora que se ha generado nuestra relación, será necesario mandar nuestras categorías creadas hacia los formularios de editar y crear un nuevo artículo. Para poder recoger todas las categorías y que estas puedan ser mostradas en un select_tag usaremos el hash .map en nuestro controlador de artículos:

@categories = Category.all.map { |result| [result.name, result.id] }

El método .map itera en función a lo que se indique, y creando un arreglo con todos los resultados obtenidos. En este caso, podemos usarlo para iterar sobre Category.all y capturar todas las categorías para tener un arreglo de todas ellas, pero por cada categoría, se creará una arreglo [result.name, result.id] que contiene su nombre y id poder ser usadas en el form, teniendo como resultado en @categories un vector.

Debido a que esta línea debería encontrarse tanto en edit como en new, se opta por crear un before_action para que funcione en solo en estos dos casos only: [:new, edit] y evitar reescribir el mismo código:

(clic para agrandar)
(clic para agrandar)


Ya están accesibles nuestras categorías, ahora será necesario en el formulario incluir un select_tag el cual se encargará de mostrar la lista desplegable de categorías disponibles, y es donde interviene options_for_select(@categories) recogiendo los dos valores que se declararon anteriormente con el método .map el primero es el name, que será la etiqueta que se mostrará en la lista, y el segundo será el id, que representa su valor y el cuál será el que sea guardado en la BD en el campo category_id generando la relación.

= select_tag :category_id, options_for_select(@categories), :prompt => "Tipo de artículo"

(clic para agrandar)


5.- Ahora, se creará otro before_action para poder guardar los parámetros que se cambien a la hora de editar la categoría de un artículo, por lo cual, este será llamado en edit y en create (debido a que cuando se llame a este método, debe pasar el parámetro ID que se le asigno a la hora de llenar el formulario)

@article.category_id = params[:category_id]


en este caso, se definirá article_update

def article_update
      @article.category_id = params[:category_id]
end


(clic para agrandar)

(clic para agrandar)


Con esto, estará completa nuestra implementación de categorías en los artículos. Ya es posible clasificar nuestro contenido al momento de crearlo o editarlo y guardar dicha relación en la BD.

A partir de aquí de puede ir por diferentes vías dependiendo cómo mostrar el catálogo que se desarrolló. Como ejemplo cualquiera, se implementa aquí un menú superior, que servirá para acceder a los artículos, ordenados según su categoría.

jueves, 7 de julio de 2016

Migraciones en Ruby on Rails (Modificar y Borrar tablas)

Las migraciones nos permiten modificar las tablas en nuestras bases de datos, agregando nuevos campos, quitando o modificando los existentes.

Haciendo un rake db:rollback deshacemos los últimos cambios generados en la base de datos, pero no es lo más correcto solo modificar el schema o migración existente para después hacer un rake db:migrate (aunque el proceso puede ser válido siempre y cuando se esté trabajando unicamente en entorno de desarollo). El proceso correcto sería creando una nueva migración y que esta sea la encargada de hacer las modificaciones necesarias.


**Algunos comandos de ayuda en la consola de rails (rails console)

1.- Consultar las tablas que hay en nuestra aplicación:

     ActiveRecord::Base.connection.tables


2.- Consultar las columnas de nuestra tabla de una manera ordenada (usando el .map{})

    ActiveRecord::Base.connection.columns("nombre_tabla").map{|c| [c.name, c.type]}


3.- Borrar una tabla en especifico:

    ActiveRecord::Migration.drop_table(:articles)


O a través de una 2da migración como se ve aquí:
MODIFICAR EL LINK DE BORRAR TABLA ARTICLES

Modificar una tabla con una migración

Las migraciones que se vayan creando en el proyecto, se irán nombrando de la siguiente manera: YYYYMMDDHHMMSS_nombre_de_la_migracion.rb que con esto se puede entender que se guardar en un "instante del tiempo" para definir el orden correcto de las migraciones, es decir, que cada una vaya siguiendo su patrón correcto de ejecución para evitar conflictos entre las diferentes versiones de cambios y que estos pudieran tener repercusiones en la tabla destino.


Se ejemplifica que se ha creado un scaffold (igual se puede usar en caso de haber creado solo el modelo)que contendría los siguientes campos:

     rails generate scaffold Article name description:text pricing:decimal user:references


Caso 1: Añadir nuevos campos a la tabla Articles

1.- Se crea la migración, ejecutando este comando en cosola, donde AddColumnWidthHeightToArticles es el nombre que llevará la migración, este es arbitrario y puede nombrarse al gusto, en este caso, se pretende especificar qué será lo que hará la migración

     rails generate migration AddColumnWidthHeightToArticles


2.- Esto nos genera un archivo de migración en db/migrate y aquí es dónde indicaremos que acción se generará:

(Clic para agrandar)
  def change
    add_column :articles, :width, :decimal, scale: 2, precision: 5
    add_column :articles, :height, :decimal, scale: 2, precision: 5
  end

add_column será el método que queremos realizar.
:articles es el primer parametro, el cual indica la tabla a la que realizará la acción.
:witdh será el nombre del campo que añadirá la migración.
:decimal será el tipo de campo.
scale: 2 Como el campo es un decimal, aquí indicaremos que se conformará por 2 digitos después del punto decimal.
precision; 5 indicará el número total que conformará nuestro decimal, en este caso, serán 5, que con el valor anterior se entiende que el número se conformará por 3 números antes del punto y 2 después de él.

De la misma manera que se hizo con scale y precision, se podrán ir indicando qué otras caracteristicas tendrá nuestro campo, como por ejemplo: index: true, foreign_key: true, default: "valor_por_defecto", etc


Ahora que sabemos como funciona la estructura, podemos modifcar un poco el comando ejecutado en el primer punto, cambiando el nombre que se indicó de la migración

     rails generate migration AddCommentsToArticles comments:string

Al ejecutarlo de esta manera, le estamos indicando al generador, que el archivo que creará tendrá como contenido un add_column con un campo llamado commets del tipo string:

(Clic para agrandar)

Se pueden añadir la cantidad de campos que se desee, solo es necesario separar con un espacio los campos que se incluirán:

     rails generate migration AddDetailsToArticles comments:string witdh:decimal height:decimal

3.- En esta, y en todas las migraciones, finalizamos con rake:db migrate para correr las migraciones y procesa al borrado de la tabla




Caso 2: Quitar campos de la tabla Articles

1.- Podemos usar el último comando visto para así poder eliminar una columna sin necesidad de modificar el archivo de migración

     rails generate migration RemoveCommentsFromArticles commens:string

(Clic para agrandar)



Caso 3: Cambiar tipo de campo en la tabla Articles

1.- Para generar cambios al tipo de campo, usaremos change_column usando como ejemplo el campo que se creó anteriormente de comments declarado como un string, ahora lo cambiaremos a un text

  def change
    change_column :articles, :comments, :text
  end

(clic para agrandar)



Caso 4: Renombrar campos en la tabla Articles

1.- Con rename_column se puede cambiar el nombre del campo, en este caso se está cambiando de nombre a comments para que sea ahora opinions:


  def change
    rename_column :articles, :comments, :opinions
  end

(clic para agrandar)


Caso 5: Modificando la estructura de la tabla

Al momento de crear un modelo o un scaffold, este genera una migración que contiene el objeto create_table y sobre este se genera la estructura. Por lo tanto, podemos hacer uso de un objeto similar para reestructurar nuestra tabla con parte de lo visto, en este caso, usaremos change_table:

  def change
change_table :articles do |t|
t.string :color #Añade un campo llamado color de tipo string
  t.remove :opinions, :widht, :height #Remueve los campos opinions, width y height
  t.rename :name, :title #Renombra el campo name por title
end
  end


(clic para agrandar)



Definiciones complementarias para el método Change:

  • add_column
  • add_index
  • add_reference
  • add_timestamps
  • add_foreign_key
  • create_table
  • create_join_table
  • drop_table
  • drop_join_table
  • remove_timestamps
  • rename_column
  • rename_index
  • remove_reference
  • rename_table


Caso 6: Borrando la tabla con migraciones


Para este caso usaremos los métodos UP y DOWN quienes se encargarán de llevar a cabo el borrado de la tabla. Al usar estos métodos estamos indicando a rails que hacer en la migración y qué hacer al revertir con rollback. Dentro de UP escribiremos las acciones que queremos que lleve a cabo la migración, mientras que en DOWN que será lo que tendría que hacer en caso de hacer un rollback.

En caso de usarse en un caso más complejo de manipulación, se seguirá el mismo principio de ordenamiento de rails, es decir, en DOWN escribiremos el inverso "de abajo a arriba" en el orden que se fueron definiendo dentro de UP.

En el caso de que una migración se vuelva compleja y no se pueda revertir lo ejecutado, por ejemplo, los datos perdidos al borrar un campo/tabla que no pueden volverse a recuperar, entonces dentro de DOWN se puede escribir raise ActiveRecord::IrreversibleMigration y con esto estamos indicando a rails que el rollback no podría ejecutarse, y en caso de hacerlo, arrogaría un error y no ejecutaría el comando. 

1.- Se crea la migración:
    rails generate migration DropPruebasTable


2.- Esto nos genera un archivo de migración en db/migrate y aquí es dónde indicaremos que acción se generará, en este caso, el borrado de la tabla:

  def up
    drop_table :pruebas
  end

  def down
    raise ActiveRecord::IrreversibleMigration
  end

(clic para agrandar)



**Para tener toda la información completa acerca de las Migraciones:
Fuente

martes, 31 de mayo de 2016

Crear | Borrar un scaffold y migración de Ruby on Rails

Crear Scaffold


El scaffold nos permite crear un CRUD, es decir, las operación una base de datos, como crear, modificar, eliminar etc. agilizando el proceso de desarrollo de nuestra aplicación.

1.- En consola, escribiremos el siguiente comando, Article hace referencia al modelo a generar, que a su vez, creara la tabla y controlador articles, debido a su gestión de rails, por lo cual es recomendable usar términos en inglés. Nombre, precio, descripción, medidas y user:refences son los campos de la tabla, y user está indicando que se hará una referencia al modelo user (que ya debe estar creado), asignando al mismo campo su llave foránea. Los campos van acompañados del tipo de dato a introducir, y los que quedan solos, se asume por defecto que serán un string:

    rails generate scaffold Article nombre descripcion:text precio:decimal medidas user:references


2.- Esto nos generará una migración, por lo cual será necesario correr el comando:

    rake db:migrate


Borrar Scaffold


Si por error se ha creado mal el scaffold y es necesario eliminarlo, se puede revertir el proceso junto con la migración:

1.- Ruby cuenta con un método que puede eliminar lo que le indiquemos dentro de nuestro proyecto, el cual es destroy y con él eliminaremos los archivos creados por el scaffold, donde article es el nombre del mismo:

    rails destroy scaffold article


2.- Ahora, toca turno de eliminar la migración, en este caso, en lugar de unas una g de generate (ej. rails g devise...) usaremos una d correspondiente a delete, indicamos que es una migración y a continuación el nombre de la misma

    rails d migration create_articles


3.- Se ha borrado la migración, pero también será necesario borrar la tabla. Se puede eliminar a través de la consola de rails con el comando:

    ActiveRecord::Migration.drop_table(:articles)


4.- Ya podemos volver a generar el scaffold (si es lo que buscamos) modificando lo necesario según sea nuestro requerimiento, de la misma manera aquí escrita, también corriendo después el rake db:migrate para la migración.



viernes, 27 de mayo de 2016

Login de usuarios en Ruby on Rails

Para el login de usuarios se ocupará una gema llamada "devise" en este caso, iremos a nuestro archivo gemfile (que se encuentra en la raíz del proyecto) y agregar la línea:

  gem "devise"


(clic para agrandar)


Después de esto, como cualquier gema, será necesario ejecutar en la terminal (situado en la carpeta correspondiente del proyecto) el comando bundle install para poder instalar la gema correctamente. Una vez instalada, correremos un generador de instalación, esto, porque algunas gemas incluyen generadores para instalar todo el proceso de la gema, esto será con:

  rails g devise:install

Después de correr este comando, la terminal nos arrojará 4 acciones que debemos seguir para tener correctamente funcionando devise:

1.- Tener las acciones por default del action_mailer para poder enviar correos referentes a la autenticación del usuario. Abriremos el archivo que indica: config/environments/development.rb y agregaremos:

  config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }

**Ruby on Rails trabaja con 3 entornos: desarrollo (que es el del ejemplo), test y producción, por lo cual, si se está trabajando en producción, será necesario cambiar 'localhost' por el dominio de la aplicación y el puerto 3000 por el 80. 


2.- Definir una URL para el root del sitio, del cual necesitaremos un controlador y una acción, con su respectiva vista, como en este otro apunte:


3.- Activar los flash messages para poder visualizar las alertas a la hora de loguearse. Aquí, deberemos icluirlas en alguna parte de nuestro código, en mi caso, las ubiqué en el layout principal para que cargara en todas las vistas:

<p class="notice"><%= notice %></p>
<p class="alert"><%= alert %></p>



4.- Este paso solo se tomará en cuenta si se está haciendo el deploying en heroku usando rails 3.2

5.- El paso número 5, será opcional por si se quieren customizar las vistas, aunque parezca que es obvio que debemos hacerlo, puede que por el momento se necesite completar la funcionalidad y después darle diseño, y podremos correr el comando rails g devise:views en cualquier otro momento.


Una vez completados los 5 pasos, tendremos que tener un modelo, en este caso, podemos cambiar User por cualquier otro en particular, no es necesario que nuestra tabla se llame users, el nombre es abierto a cualquier otro:

  rails g devise User

Esto nos estaría generando un modelo llamado user y una tabla llamada users (por la convención de Rails de generar el plural, por eso es muy recomendable que siempre se usen términos en inglés para que rails pueda generar el plural en base a lo escrito). De igual manera, se crea una migración en db/migrate/201806..._devise_create_users.rb así que será necesario correr la migración, así que en la terminal se ejecutará:

  rake db:migrate

De esta manera, se ha creado con éxito un login de usuarios, ahora podemos ir al navegador e ingresar a users/sign_in o users/sign_up y verificaremos que ya están activos. Podemos crear algunos usuarios para comprobar su funcionamiento, y que las alertas también están haciendo su trabajo:

(clic para agrandar)

(clic para agrandar)

(clic para agrandar)



** Con rails g devise:views se crearían las vistas correspondientes a estas pantallas, y podemos modificarlas a gusto, ahora que se verificó que todo funciona, sería buen momento para correrlo.






lunes, 23 de mayo de 2016

Form Builder (Customizar forms en Ruby on Rails)

Si se necesita cambiar la estructura en la que se presentan los formularios, podemos crear nuestro propio form builder para personalizar plantilla, y poder reutilizarla en todos los formularios que deseemos.

Esto podría ser relacionado a crear un parcial, pero en este caso, se trata de un layout especial para los formularios para poder hacerlos dinámicamente, ahorrándonos bastantes líneas de código y aprovechando el potencial que rails nos brinda.

Se muestra como ejemplo un formulario de creación de un Artículo, creado a través de un scaffold. Se modificará su estructura para también simplificar su contenido y mostrar el formulario con las clases de bootstrap.



Esta sería la estructura común que tendría un formulario:
**Notar que para el HTML se está usando HAML


(clic para agrandar)


1.- Lo primero será crear la carpeta dentro que contendrá todos los forms. La carpeta se deberá nombrar como form_builders y dentro de ella crearemos el archivo que contendrá la estructura. El nombre del mismo, es a criterio propio, pero una vez creado, la clase declarada deberá coincidir con el archivo.

(clic para agrandar)


2.- Se limpiará todo el código del form de articulos, los divs, labels y errores se removerán para solo dejar las impresiones de los campos. y se indicará en la parte superior, que este formulario usará el builder BootstrapFormBuilder, haciendo referencia a la clase creada en el punto anterior:

     = form_for @article,builder: BootstrapFormBuilder do |f|

(clic para agrandar)


3.- Se puede ver desde el punto anterior, como se ha reducido el código, mostrándose de una manera más sencilla y legible. Cada campo en el formulario contiene un método, este recibe el nombre según el tipo al que pertenece, errors es el método que contiene los errores del formulario, text_field es el método que indica que el input es de tipo text, etc. Cada uno de ellos deberá definirse en nuestro builder BootstrapFormBuilder, para que puedan ser usados.

El primero a definir será el método para los errores:

def errors
if object.errors.any?
content_tag :div, class:"alert alert-dismissible alert-danger" do
content_tag(:h2, "Errores") +
content_tag(:ul) do
list = ""
object.errors.full_messages.each do |error|
list += content_tag :li, error
end
list.html_safe
end
end
end
end

Primero se validará con un if si existen errores, de ser así, entonces los imprimirá. Cuando queremos definir qué será lo que mostrará nuestro método, podemos usar content_tag el cuál nos ayudará a desplegar el HTML(HAML). Si queremos anidar los divs por ejemplo, usaremos un do, esto es un bloque que indicará que el contenido estará dentro del mismo, ejemplo:

HAML:

.container 
.col-md-8
%h2 Título


content_tag:

content_tag :div, class:"container" do
content_tag :div, class:"col-md-8" do
content_tag :h2, "Titulo"
end
end


Se crea una lista (en primer instancia, vacía), y esta recibirá cada uno de los mensajes de error arrojados por la iteración que estamos haciendo a object.errors y finalmente los mostramos como un html.

Al estar creando nuestro propio builder, content_tag no está declarado, ya que ese se encuentra en la estructura original, y para eso es necesario que se declaré en nuestro builder. En lugar de eso, aprovecharemos los helpers de rails y delegaremos a @template (que es dónde está declarado content_tag) al nuestro, y de esta manera podemos usarlo dentro de nuestro builder. Al final, el código debería verse de esta menera:

(clic para agrandar)



4.- Definir el método text_field. Primero se observará el tipo de estructura que usa bootstrap para la creación de formularios, viendo que cada campo se encuentra dentro de un div.form-group y dentro se encuentra el label y el tipo de input, que en este caso se define a través de nuestro método:

(clic para agrandar)


Así que con esa estructura, procedemos a crear nuestro método para todos los input que sean de tipo text:


def text_field name, *args
options = args.extract_options!

if options.has_key?(:class)
options[:class] += "form-control"

else
options[:class] = "form-control"
end

content_tag :div, class:"form-group" do
content_tag(:label, name, name: name ) + super(name,options)
end
end


En la declaración del método se escribirán qué parámetros recibirá, en este caso, será name, el cual contiene el nombre del campo y *args que este se usará en caso de que se quiera definir clases personalizadas a cada input además de que se debe declarar por defecto (form-control). A raíz de este 2do parámetro, se indica la validación, donde options será el hash que extraerá los argumentos que se escribieron en cada campo y se validará si existen nuevas clases, de ser así, options tendrá la clase por defecto, más la(s) clase(s), de lo contrario, solo tendrá la clase por defecto, es decir:

En nuestro form, para definir una nueva clase lo deberemos poner como 2do parametro, de lo contrario, solo asignará por defecto la clase form-control:


f.text_field :name, class: "mi-clase mi-clase-2 "


Finalmente, se escribe el content_tag que imprimirá nuestras estructura del form, donde se usa un super, que es una palabra reservada de ruby, que llama al método de la clase padre. En este caso, estaría mandando a llamar al método de FormBuilder que es nuestra clase padre, dónde se generarán los controles según los parámetros que estamos enviando, contenidos en name y options (el nombre del campo y las clases generadas) algo parecido como se hizo anteriormente con @template. De esta manera, se está creando el content_tag con el label y el super con el input.


Este método quedaría enteramente reutilizable para los demás inputs que se necesiten, solo sería cuestión de copiar el código para crear un segundo método, y cambiar el text_field por text_area, url_field, email_field, etc..




5.- Refactoring del código. El generar muchos métodos que hacen exactamente lo mismo, no sería lo más apropiado, y se debería seguir la filosofía de "Don't repeat yourself", por lo cuál, se reestructuraría el código, para que en lugar de generar muchos métodos iguales, generaríamos un pequeño snippet para que los métodos sean autogenerados dinámicamente, y esto es conocido cómo metaprogramming:


[:text_field,:text_area,:url_field,:email_field,:number_field].each do |metodo|
define_method metodo do |name,*args|
options = args.extract_options!
additional_classes = "form-control floating-label"
if options.has_key?(:class)
options[:class] += additional_classes
else
options[:class] = additional_classes
end
options[:placeholder] = name.capitalize
content_tag :div, class:"form-group margenss" do
super(name,options)
end
end
end


(clic para agrandar)


Dentro de un arreglo, incluiremos los nombres de los métodos que contendrían el mismo código, después, estos se irán iterando con un each e irán siendo guardados en la variable metodo. Se hace uso del método define_method que como su nombre indica, se encarga de definir un método, y este será según la iteración con la variable metodo, pasándole los parametros de name y *args.

Se agrega la variable additional_classes la cuál contiene las clases por defecto para los input (por cuestión de estilos se añadió la 2da clase floating-label para dar usar los forms de material design) y esta clase ahora es usada en las validaciones del options.has_key.

Se declara el options[:placeholder] = name.capitalize para que los placeholders tengan letra capital (recordar que options recoje todos los argumentos que van en el después del name en el form, es por eso que podemos usar los símbolos como :class, :placeholder, :id, etc), y finalmente, se eliminó la impresión del label y simplemente se dejó el input generado por el super.



6.- El botón de submit. Una vez construido todo el form dinámico, solo quedaría definir nuestro submit para poder generar el botón guardar los artículos. De igual manera, el método recibe los argumentos(*args) que se definan en el form, se añade el bloque del content_tag para que todo esté dentro de un div y finalmente se muestra el super con los argumentos recibidos y con una clase por defecto:


def submit(*args)
content_tag :div do
super(*args,class:"btn btn-success")
end
end



El resultado final de este formbuilder sería el siguiente:


(clic para agrandar)



(clic para agrandar)









jueves, 3 de marzo de 2016

Crear un controlador y usarlo como página principal

Después de haber instalado correctamente Rails, seguiría crear un controlador y hacerlo ver como nuestra página principal.

Nota:
Todo lo trabajado, se usa a partir del proyecto ya creado cuando se hizo la instalación.



1.- Crearemos el controlador con la siguiente sintaxis:

rails generate controller principal index

Donde:
principal => nombre del controlador que vamos a crear
index => nombre de la función que el controlador va a llamar
(pueden poner cualquier nombre)


2.- Esto nos generará 2 nuevos archivos dentro de nuestra aplicación y podemos comprobarlo en la ruta de controladores y de vistas, ambos con los nombres que escogimos.
El archivo de la vista, es un html y lo modificamos para comprobar su funcionamiento en:

localhost:3000/principal/index

(Recuerda que primero se debe levantar el servidor para poder visualizarlo)

(clic para hacer grandota)



Usando nuestro controlador como vista principal.


Haremos que este nuevo controlador, sea visible desde la vista principal, para convertirlo en el front de nuestro sitio:

1.- Vamos a dirigirnos a la carpeta de config y abriremos el archivo llamado routes.rb

2.- Dentro de ella vamos a encontrar una línea comentada de root, podemos usar esa, o podemos añadir una nueva, usando nuestro controlador antes creado:

(clic para hacer grandota)

3.- Regresamos al navegador, escribimos localhost:3000 y deberíamos estar viendo nuestra vista recién creada.


Nota:
La cadena de la línea 2, que comienza con get, le está indicando a rails que después de localhost:3000/ existe esa ruta, si la comentamos/borramos, al tratar de acceder a localhost:3000/principal/index marcaría un error de que dicho path no existe.