Advertisement
  1. Code
  2. Ruby
  3. Ruby on Rails

Uso de JavaScript discreto y AJAX con Rails 3

Scroll to top
Read Time: 9 min

() translation by (you can also view the original English article)

Como mencioné en mi tutorial anterior de Ruby on Rails, JavaScript discreto (UJS) es una de las características nuevas más interesantes de Rails 3. UJS permite que el código generado por Rails sea mucho más limpio, ayuda a separar la lógica de JavaScript de tus diseños HTML y desacopla Rails de la biblioteca Prototype JavaScript.  En este tutorial, veremos estas características y aprenderemos a usarlas en una aplicación simple de Rails 3.


Antecedentes: ¿Qué es JavaScript discreto?

Para empezar, ¿qué es exactamente UJS? Simplemente, UJS es JavaScript que está separado de tu marcado HTML. La forma más sencilla de describir UJS es con un ejemplo. Toma un controlador de eventos onclick; podríamos agregarlo de manera intrusiva:

1
<a href='#' onclick='alert("Inline Javscript")'>Link</a>

O podríamos agregarlo discretamente adjuntando el evento al enlace (usando jQuery en este ejemplo):

1
<a href='#'>Link</a>
2
<script>
3
$('a').bind('click', function() {
4
    alert('Unobtrusive!');
5
}
6
</script>

Como mencioné en mi introducción, este segundo método tiene una variedad de beneficios, incluida una depuración más fácil y un código más limpio.

"Rails 3, por otro lado, es independiente del marco de JavaScript. En otras palabras, puedes usar el marco de JavaScript que elijas, siempre que exista una implementación de Rails UJS para ese marco".

Hasta la versión 3, Ruby on Rails generaba JavaScript intrusivo. El código resultante no estaba limpio, pero lo que es peor, estaba estrechamente acoplado al marco Prototype JavaScript.  Esto significaba que, a menos que creara un complemento o pirateara Rails, tenía que usar la biblioteca Prototype con los métodos auxiliares de JavaScript de Rail.

Rails 3, por otro lado, es independiente del marco de JavaScript. En otras palabras, puedes usar el marco de JavaScript que elijas, siempre que exista una implementación de Rails UJS para ese marco. Las implementaciones actuales de UJS incluyen lo siguiente:

Rails 3 ahora implementa toda su funcionalidad JavaScript Helper (envíos AJAX, mensajes de confirmación, etc.) de manera discreta al agregar los siguientes atributos personalizados de HTML 5 a los elementos HTML.

  • método de datos: el método REST que se utilizará en los envíos de formularios.
  • confirmación de datos: el mensaje de confirmación que se debe usar antes de realizar alguna acción.
  • data-remote: si es verdadero, envíalo a través de AJAX.
  • data-disable-with: deshabilita los elementos del formulario durante el envío de un formulario

Por ejemplo, esta etiqueta de enlace

1
<td><a href="/posts/2" class="delete_post" data-confirm="Are you sure?" data-method="delete" data-remote="true" rel="nofollow">Destroy</a></td>

enviarías una solicitud de eliminación de AJAX después de preguntar al usuario "¿Estás seguro?"

Puedes imaginarte cuánto más difícil de leer sería si todo ese JavaScript estuviera en línea.

Ahora que hemos revisado UJS y cómo Rails implementa UJS, configuremos un proyecto y veamos algunas aplicaciones específicas. Usaremos la biblioteca jQuery y la implementación de UJS en este tutorial.


Paso 1: configuración del proyecto

Dado que estamos creando un nuevo proyecto desde cero, lo primero que debemos hacer es crear el proyecto escribiendo lo siguiente:

1
	rails new blog --skip-prototype

Ten en cuenta que le estoy indicando a Rails que omita el prototipo de archivo JavaScript, ya que voy a usar la biblioteca jQuery.

Iniciemos el servidor solo para asegurarnos de que todo parece estar funcionando.

¡Y voilá!

Ahora que hemos configurado nuestro proyecto, necesitamos agregar jQuery y jQuery UJS a nuestro proyecto. Puedes organizar tu JavaScript como desees, pero la convención de Rails para estructurar tus archivos JavaScript es la siguiente (todos estos archivos van en público / javascripts):

  • archivo JavaScript de framework (jquery.js, prototype.js o mootools.js)
  • rails.js: el código que implementa rails UJS (para cualquier marco que hayas elegido)
  • application.js - tu aplicación JavaScript

Si aún no lo has hecho, descarga jquery.js (o consulta un CDN) y rails.js e inclúyalos en tu directorio public / javascripts.

Lo último que tenemos que hacer para ponernos en marcha es decirle a Rails que incluya estos archivos js en cada una de nuestras páginas. Para hacer esto, abre application.rb en tu directorio de configuración y agrega la siguiente línea

1
config.action_view.JavaScript_expansions[:defaults] = %w(jquery rails application)

Este elemento de configuración le dice a Rails que incluya los tres archivos JavaScript mencionados anteriormente de forma predeterminada.

Alternativamente, puedes tomar jQuery de un CDN (es decir, http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js) al incluir manualmente una etiqueta de script que apunte a la ubicación correcta. Si haces esto, asegúrate de eliminar 'jquery' del elemento de configuración JavaScript_expansions.


Paso 2: generar código

Para demostrar la funcionalidad de Rails UJS, primero tendremos que tener algún código con el que trabajar. Para esta demostración, solo tendremos un objeto Post simple. Generemos eso ahora

1
	rails generate scaffold Post name:string title:string content:text

Y luego migremos nuestra base de datos para crear la tabla de publicaciones.

1
	rake db:migrate

Ok, ¡estamos listos para ir! Si navegamos a http: // localhost: 3000 / posts / new, deberíamos ver un formulario para crear una nueva publicación.

¡Está bien, todo está funcionando! Ahora profundicemos y veamos cómo usar la funcionalidad UJS y AJAX incorporada en Rails.


Paso 3: agregar AJAX

Ahora que se incluyen todos los archivos JavaScript necesarios, podemos empezar a utilizar Rails 3 para implementar algunas funciones AJAX. Aunque puedes escribir todo el JavaScript personalizado que desees, Rails proporciona algunos buenos métodos integrados que puedes utilizar para realizar fácilmente llamadas AJAX y otras acciones de JavaScript.

Veamos un par de ayudantes de rieles de uso común y el JavaScript que generan.

Envío de formularios AJAX y archivos ERB de Javascript

Si miramos nuestro formulario de Publicaciones, podemos ver que cada vez que creamos o editamos una Publicación, el formulario se envía manualmente y luego se nos redirige a una vista de solo lectura de esa Publicación. ¿Qué pasaría si quisiéramos enviar ese formulario a través de AJAX en lugar de utilizar un envío manual?

Rails 3 facilita la conversión de cualquier formato a AJAX. Primero, abre tu _form.html.erb parcial en app / views / posts, y cambia la primera línea de:

1
<%= form_for(@post) do |f| %>

para

1
<%= form_for(@post, :remote => true) do |f| %>

Antes de Rails 3, agregar: remote => true habría generado un montón de JavaScript en línea dentro de la etiqueta del formulario, pero con Rails 3 UJS, el único cambio es la adición de un atributo personalizado HTML 5. ¿Puedes distinguirlo?

1
<form accept-charset="UTF-8" action="/posts" class="new_post" data-remote="true" id="new_post" method="post">

El atributo es data-remote = "true", y Rails UJS JavaScript se une a cualquier formulario con ese atributo y lo envía a través de AJAX en lugar de un POST tradicional.

Eso es todo lo que se necesita para hacer el envío AJAX, pero ¿cómo realizamos una devolución de llamada después de que regrese la llamada AJAX?

La forma más común de manejar una devolución de una llamada AJAX es mediante el uso de archivos ERB de JavaScript. Estos funcionan exactamente como tus archivos ERB normales, pero contienen código JavaScript en lugar de HTML. Probémoslo.

Lo primero que debemos hacer es decirle a nuestro controlador cómo responder a las solicitudes de AJAX. En posts_controller.rb (app / controllers) podemos decirle a nuestro controlador que responda a una solicitud AJAX agregando

1
format.js

en cada bloque respond_to que vamos a llamar vía AJAX. Por ejemplo, podríamos actualizar la acción de creación para que se vea así:

1
def create
2
    @post = Post.new(params[:post])
3
4
    respond_to do |format|
5
      if @post.save
6
        format.html { redirect_to(@post, :notice => 'Post created.') }
7
        format.js
8
      else
9
        format.html { render :action => "new" }
10
        format.js
11
      end
12
    end
13
end

Debido a que no especificamos ninguna opción en el bloque respond_to, Rails responderá a las solicitudes de JavaScript cargando un ERB .js con el mismo nombre que la acción del controlador (create.js.erb, en este caso).

Ahora que nuestro controlador sabe cómo manejar las llamadas AJAX, necesitamos crear nuestras vistas. Para el ejemplo actual, agrega create.js.erb en tu directorio app / views / posts.  Este archivo se renderizará y el JavaScript interno se ejecutará cuando finalice la llamada. Por ahora, simplemente sobrescribiremos la etiqueta del formulario con el título y el contenido de la publicación del blog:

1
	$('body').html("<h1><%= escape_javaScript(@post.title) %></h1>").append("<%= escape_javaScript(@post.content) %>");

Ahora, si creamos una nueva publicación, obtenemos lo siguiente en la pantalla. ¡Éxito!

La ventaja de este método es que puedes intercalar el código ruby ​​que configuró en tu controlador con tu JavaScript, lo que hace que sea realmente fácil manipular tu vista con los resultados de una solicitud.

Devoluciones de llamada AJAX mediante eventos JavaScript personalizados

Cada implementación de Rails UJS también proporciona otra forma de agregar devoluciones de llamada a nuestras llamadas AJAX: eventos JavaScript personalizados.  Veamos otro ejemplo. En nuestra vista de índice de Publicaciones (http: // localhost: 3000 / posts /), podemos ver que cada publicación se puede eliminar a través de un enlace de eliminación.

Vamos a AJAXificar nuestro enlace agregando: remote => true y adicionalmente dándole una clase CSS para que podamos encontrar fácilmente este POST usando un selector CSS.

1
<td><%= link_to 'Destroy', post, :confirm => 'Are you sure?', :method => :delete, :remote=>true, :class=>'delete_post' %></td>

Lo que produce el siguiente resultado:

1
<td><a href="/posts/2" class="delete_post" data-confirm="Are you sure?" data-method="delete" rel="nofollow">Destroy</a></td>

Cada llamada de rails UJS AJAX proporciona seis eventos personalizados que se pueden adjuntar a:

  • ajax: before - justo antes de la llamada ajax
  • ajax: loading - antes de la llamada ajax, pero después de que se crea el objeto XmlHttpRequest)
  • ajax: éxito - llamada ajax exitosa
  • ajax: error - llamada ajax fallida
  • ajax: completo: finalización de la llamada ajax (después de ajax: éxito y ajax: error)
  • ajax: after - después de que se envíe la llamada ajax (nota: no después de que regrese)

En nuestro caso, agregaremos un detector de eventos al evento ajax: success en nuestros enlaces de eliminación, y haremos que la publicación eliminada se desvanezca en lugar de volver a cargar la página. Agregaremos el siguiente JavaScript a nuestro archivo application.js.

1
	$('.delete_post').bind('ajax:success', function() {
2
		$(this).closest('tr').fadeOut();
3
	});

También necesitaremos decirle a nuestro posts_controller que no intente renderizar una vista después de que termine de eliminar la publicación.

1
  def destroy
2
    @post = Post.find(params[:id])
3
    @post.destroy
4
5
    respond_to do |format|
6
      format.html { redirect_to(posts_url) }
7
      format.js   { render :nothing => true }
8
    end

Ahora, cuando eliminemos una publicación, desaparecerá gradualmente.


Conclusión

Bueno, ahí lo tienes. Ahora sabes cómo hacer llamadas AJAX usando Rails 3 UJS. Si bien los ejemplos explicados fueron simples, puedes usar estas mismas técnicas para agregar todo tipo de interactividad a tu proyecto.  Espero que estés de acuerdo en que es una gran mejora con respecto a las versiones anteriores y que lo probarás en tu próximo proyecto de Rails.

¿Qué técnicas usas al implementar AJAX en Rails?

Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.