Rails 3 Ajax form en backbone y coffeescript

Rails 3 Ajax form en backbone y coffeescript

En este caso quiero comenzar con el increible mundo ajax y en este ejemplo voy a utilizar backbone y coffeescript para lo cual presupongo que ya tienen un sitio en rails 3 con sus backbone install y toda la cosa, listos para hacer sus pruebas en este caso realizare dos distintos formularios simulando en uno un login al cual le falta la funcionalidad de logeo pero para efectos de esto solo es de ejemplo y ya ustedes le meten su logica en el controlador de acuerdo a sus necesidades para que funcione el autenticate o si quieren usar la gema devise, eso se los dejo a su eleccion.[divider] En caso de que tengan problemas pueden visitar el repo que a continuacion les dejo y en la parte del README file pueden encontrar toda la informacion para inicializar su instalacion en backbone con rails 3 y ya apartir de esto pueden continuar con el tutorial. [clear] https://github.com/heridev/login-en-backbone [divider] Primero tenemos que crear nuestra nueva aplicacion para aplicarle el backbone esto lo hacemos de la siguiente forma

1
2
3
$ rails new heridev
 
$ cd heridev

Los primero que debemos de hacer ahora es crear un controlador de ejemplo para poder hacer todas nuestras pruebas en el mismo le vamos a llamar controlador sessions y lo creamos con el generator de rails

1
$ rails g controller sessions index --skip javascript

Ahora modificamos nuestra vista ubicada en

1
 app/view/sessions/index.html.erb

y la renombramos para poder utilizar haml (debemos de agregar la gema “gem ‘haml'” a nuestro archivo Gemfile) y quedaria con el siguiente nombre

1
 app/view/sessions/index.html.haml

Su contenido del archivo sera muy simple

1
2
%h1 Identifiquese
#form-area

Borramos el archivo ubicado en

1
public/index.html.erb

y ahora debemos de modificar nuestro archivo

1
config/routes.rb

y cambiamos las lineas para que lo primero que se muestre en nuestra aplicacion sea la vista de sessions_controller index, entonces para eso modificamos lo siguiente en el archivo

1
2
get 'sessions/index'
root to: 'sessions#index'

Y ahorita ya podemos correr nuestra aplicacion para ver que se muestre correctamente nuestra aplicacion

1
2
$ bundle install
$ rails server or only rails s

y si visitamos en nuestro navegador la siguiente url

1
http://localhost:3000

Podemos visualizar nuestra aplicacion que por el momento solo muestra un titulo de identifiquese Ahora vamos a continuar con la configuracion de nuestra aplicacion usando backbone y coffeescript Para poder utilizar coffee y backbone debemos de agregar las gemas a nuestro Gemfile, las cuales son las siguientes

1
2
gem 'backbone-on-rails'
gem 'coffee-rails'

Despues de agregarlas debemos de ejecutar nuevamente en nuestra consola

1
$ bundle install

Y lo primero para mas rapido vamos a crear nuestra estructura de archivos en backbone los cuales se crearan en la carpeta

1
app/assets/javascripts

y se crearan las carpetas de modelos, colecciones, vistas y templates estara directamente en

1
app/assets

, con el siguiente comando creamos nuestra estructura.

1
$ rails g backbone:install

Si todo funciono correctamente despues de esto al correr nuevamente nuestra aplicacion con

1
rails server

o detenemos la que esta corriendo con Ctrl + c en la consola y la volvemos a ejecutar, si funciono bien nuestra instalacion debemos de recibir una alerta en el navegador que diga welcome to backbone. En caso de que no se muestre ese mensaje lo mas seguro es que haya un error con nuestra instalacion, al comienzo me paso que el archivo ubicado en

1
app/assets/javascripts/application.js

, no estaba cargando bien los archivos javascript para eso tambien me di cuenta que habia errores en el navegaodor para ver si tienes errores y usas google chrome solo debes de dar clic derecho por ejemplo sobre el titulo de identifiquese en nuestra vista creada y seleccionar la opcion inspeccionar elemento despues de eso debemos de buscar la opcion de consola y hay se nos mostrara si tenemos problemas con javascript o backbone en caso de que asi sea entonces vamos a modificar nuestro archivo aplication.js y en mi caso cambie el require_tree por require_self algo asi luce mi archivo

1
2
3
4
5
6
7
8
9
10
11
//= require jquery
//= require jquery_ujs
//= require_self
//= require underscore
//= require backbone
//= require .//backbone_app
//= require_tree ../templates/
//= require_tree .//models
//= require_tree .//collections
//= require_tree .//views
//= require_tree .//routers

NOTA IMPORTANTE: hago especial enfasis si estan teniendo problemas y no funciona el ejemplo revisen su consola de errores, y si tienen errores concentrense en el archivo aplication.js eso era lo que me dio lata un rato, tambien tengan cuidado con la indentacion ya que hace que no funcione bien la aplicacion.Primero vamos a crear nuestros archivos como vistas, collections y templates, base para ya nomas empezarlos a modificar y agregar nuestra propia logica, para ello utilizamos el siguiente comando desde consola

1
$ rails g backbone:scaffold login

Despues de esto modificamos el archivo ubicado en

1
app/assets/javascripts/heridev.js.coffee

Y su contenido en mi caso que mi aplicacion se llama heridev pues mi contenido es

1
2
3
4
5
6
7
8
9
10
11
window.Heridev =
  Models: {}
  Collections: {}
  Views: {}
  Routers: {}
  login: ->
    new Heridev.Routers.Login()
    Backbone.history.start()
 
  $(document).ready ->
    Heridev.login()

Y listo ya tenemos todo y el primer archivo que debemos de modificar sera el router el cual esta ubicado en:

1
<app/assets/javascripts/routers/logins.js.coffee

Lo renombramos a

1
<app/assets/javascripts/routers/login_router.js.coffee

Y tendra este contenido

1
2
3
4
5
6
7
class Heridev.Routers.LoginRouter extends Backbone.Router
  routes:
    '' : 'showLoginView'
 
  showLoginView: ->
    view = new Heridev.Views.LoginView()
    $('#form-area').html(view.render().el)

Ahora vamos con nuestra vista login View que en la funcion de showLoginView estamos llamando entonces ahora buscamos nuestro archivo que se llama:

1
app/assets/javascripts/views/logins/index.js.coffee

y lo renombramos y cambiamos a:

1
app/assets/javascripts/views/login_view.js.coffee

Vamos a ingresar el siguiente codigo:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
class Heridev.Views.LoginView extends Backbone.View
 
  events:
    'click input[name="commit"]' : 'login'
 
  template: JST['login/login']
 
  render: ->
    $(@el).html(@template())
    @
 
  login: (event) ->
    event.preventDefault()
 
    $.ajax
    url: '/session/'
    type: 'post'
    data: @$('form').serialize()
    dataType: 'json'
    cache: false
    success: =>
    @$el.find('.notice-message').removeClass('alert')
    @$el.find('.notice-message').slideDown()
    @$el.find('.notice-message').addClass('success')
    @$el.find('.notice-message').html('<ul><li><strong>Successful Login!</strong></li></ul>')
    setTimeout (->
      window.location.href = "/"
    ), 1000
    error: @handleError
  handleError: (response) =>
    if response.status == 422
    @$el.find('#errors ul').html('')
    @$el.find('.notice-message').slideDown()
    @$el.find('.notice-message').addClass('alert')
    errors = $.parseJSON response.responseText
    _.each errors, (message) =>
      $('#errors ul').append('<ul><li>#{message}</li></ul>')

Ahora Pasamos al contenido de nuestro template (en mi caso uso haml en caso de problemas lo pueden convertir a html si estan usando erb hay convertidores en linea) Ahora buscamos nuestro archivo ubicado en

1
app/assets/templates/logins/login.jst.eco

y renombramos la carpeta de “logins” a “login” y metemos nuestra vista adentro de ese directorio y le ponemos extension haml o sea el archivo debe de quedar de la siguiente manera:

1
app/assets/templates/login/login.jst.eco.haml

y con el contenido de prueba siguiente

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
.login-form-container
  .login-form-container-inner
    .notice-message{style: 'display-none'}
      %span.icon
      %ul
        %li
          %strong Please correct the next errors
      #errors
        %ul
      = link_to 'Close', '#', class: "btn-close-corner"
    .box-header
      %h1.handwrited-head Bienvenido!
      %p
        %strong Identifiquese
    .box-body
      = form_tag(session_path) do
        = label_tag(:email, 'Email')
        .input-line
          = text_field_tag :email
          = label_tag(:password, 'Password')
        .input-line
          = password_field_tag :password
        .button-line
          = submit_tag "Log in", class: "btn-med"
        %p.form-note
          Did you forget your password?
          = link_to "Reset it here", "#password-recovery", id: 'recover-password'

Y continuamos ahora con nuestro controlador el cual esta ubicado en app/controllers/sessions_controller.rbY nuestro contenido en este caso solo es funcional y si ingresamos estos datos vamos a validarnos con un usuario predeterminado pero como digo solo es de ejemplo cada cual tendra que poner su propia logica o si usa alguna otra gema aqui debe de ir

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class SessionsController < ApplicationController
  respond_to :json
  def index
  end
 
  def create
    @errors= ["Usuario invalido",
              "contraseña invalida",
              "El correo no tiene un formato correcto"
             ]
   if params[:email]== "heriberto.perez@crowdint.com" && params[:password]== "12345679"
     render status: : ok, json: []
   else
     render status: :unprocessable_entity, json: @errors
   end
  end
 
end

Nota: En la parte de “: ok” separado debe de ir junto pero si lo pongo junto aparece un emotico como este :ok para que no les vaya a pasar y lo ponen en su controlador junto porfavor. Y como no podia faltar vamos a probar nuestra pequeña creacion en rspec capybara para testear lo que hemos construido a continuacion creamos nuestro archivo en la ubicacion en caso de que no exista. spec/controllers/sessions_controller_spec.rb

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
require 'spec_helper'
            describe SessionsController do
               describe 'post#create' do
                 context 'When the autentication is success' do
 
                    let(:params) do
                      {email: 'heriberto.perez@crowdint.com', password: '12345679'}
                    end
 
                    specify do
                      post :create, params
                      response.should be_success
                    end
 
                 end
 
                   context 'When the autentication is failure' do
                    let(:params) do
                     {email: 'heriberto.perez@crowdint.com', password: 'none'}
                    end
 
                    let(:errors)do
                      ["Error al momento de validarse",
                      "Usuario erroneo",
                      "password no es correcto"]
                    end
 
                    specify do
                      post :create, params
                      expect(response.status).to eq(422)
                      expect(response.body). to eq(errors.to_json)
                   end
                  end
                end
             end

Y no olvidemos agregar nuestra ruta al router para que funcione al archivo config/routes.rb agregamos la siguiente linea

1
resource :session, only: [:create]

Y esto es todo amigos!!

No Comments

Post A Comment