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


$ 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

$ rails g controller sessions index --skip javascript

Ahora modificamos nuestra vista ubicada en

 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

 app/view/sessions/index.html.haml

Su contenido del archivo sera muy simple

%h1 Identifiquese
#form-area

Borramos el archivo ubicado en

public/index.html.erb

y ahora debemos de modificar nuestro archivo

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

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

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

$ bundle install
$ rails server or only rails s

y si visitamos en nuestro navegador la siguiente url

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

gem 'backbone-on-rails'
gem 'coffee-rails'

Despues de agregarlas debemos de ejecutar nuevamente en nuestra consola

$ bundle install

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

app/assets/javascripts

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

app/assets

, con el siguiente comando creamos nuestra estructura.

$ rails g backbone:install

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

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

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

//= 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

$ rails g backbone:scaffold login

Despues de esto modificamos el archivo ubicado en

app/assets/javascripts/heridev.js.coffee

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

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:

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

Lo renombramos a

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

Y tendra este contenido

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:

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

y lo renombramos y cambiamos a:

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

Vamos a ingresar el siguiente codigo:

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

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:

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

y con el contenido de prueba siguiente

.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

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

 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

resource :session, only: [:create]

Y esto es todo amigos!!

No Comments

Post A Comment