28 Sep 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