SlideShare uma empresa Scribd logo
Globalcode	
  – Open4education
Interfaces  ricas  com  Rails  e  React.JS
Rodrigo  Urubatan
@urubatan
Globalcode	
  – Open4education
Quem?
Programador desde 1997
Trabalha com Ruby na Brightwire
Escreveu "Ruby On Rails: Desenvolvimento fácil e Rápido de aplicações web”
Já trabalhou com diversas linguagens (C, C++, Delphi, PHP, ASP, ColdFusion,
VisualBasic, C#, Python, Ruby, Assembly, …)
Apaixonado por Agile e atualmente por trabalho remoto
Patinador, Corredor, Ciclista e agora resolveu aprender Karate :D
Pai de um Guri de 6 anos
http://urubatan.com.br - Anda meio abandonado mas vai voltar
http://sobrecodigo.com - idem
Globalcode	
  – Open4education
Objetivo (O blog mais feio do
mundo!)
Globalcode	
  – Open4education
Objetivo
Usar o Rails como backend da aplicação
Toda a interação com o usuário será implementada no cliente
Validações e regras de negócio serão implementadas no servidor
(sim, eu poderia usar Sinatra mas sou preguiçoso)
Globalcode	
  – Open4education
Cuidado!
Nesta palestra vamos falar de uma SPA (Single Page Application)
Isto tem vantagens e desvantagens
Melhora muito a interação com o usuário sem duplicação de código, já que o
código de renderização fica todo no JS
Piora muito a indexação da sua aplicação por buscadores (adeus SEO - ou
não…)
Globalcode	
  – Open4education
Criando a aplicação
Uma aplicação padrão Rails (rails new …)
Gemfile updates
gem 'backbone-on-rails'
gem 'react-rails', github: 'reactjs/react-rails', ref:
'master'
Environment update (development.rb para começar)
config.react.variant = :development
config.react.addons = true # defaults to false
config.react.server_renderer =
React::ServerRendering::SprocketsRenderer
bundle install
rails g react:install
Globalcode	
  – Open4education
Componentes
Componentes javascript vão ficar em app/assets/javascript/components
Backbone.js vai facilitar a comunicação cliente/servidor
arquivos .js.jsx tem uma facilidade extra, são compilados pelo react-rails via asset
pipeline e permitem adicionar HTML inline
Globalcode	
  – Open4education
Cadastrando um Usuário
rails g scaffold post title:string slug:text content:text
Apagar todas as views do post exceto index.html.erb
Apagar todo o código de index.html.erb e mudar para:
<%= react_component('Blog', {collection: @posts, item: @post}) %>
Globalcode	
  – Open4education
Alterações no controller
Fazer todos os métodos retornarem json, mais ou menos assim (não é a melhor
tecnica, mas boa o suficiente para o exemplo)
class PostsController < ApplicationController
before_action :set_post, only: [:show, :edit, :update, :destroy]
def index
@posts = Post.all
end
def show
@posts = Post.all
render :index
end
# GET /posts/new
def new
@post = Post.new
render :index
end
# POST /posts
# POST /posts.json
def create
@post = Post.new(post_params)
respond_to do |format|
if @post.save
format.json { render json: @post, status: :created, location: @post }
else
format.json { render json: @post.errors, status: :unprocessable_entity }
end
end
end
#  PATCH/PUT  /posts/1
#  PATCH/PUT  /posts/1.json
def update
respond_to do  |format|
if  @post.update(post_params)
format.json {  render  json:  @user,  status:  :ok,  location:  @post  }
else
format.json {  render  json:  @post.errors,  status:  :unprocessable_entity }
end
end
end
#  DELETE  /posts/1
#  DELETE  /posts/1.json
def destroy
@post.destroy
respond_to do  |format|
format.json {  head  :no_content }
end
end
private
#  Use  callbacks  to  share  common  setup  or  constraints  between  actions.
def set_post
@post  =  Post.find_by(slug:  params[:id])  ||  Post.find(params[:id])
end
#  Never  trust  parameters  from  the  scary  internet,  only  allow  the  white  list  through.
def post_params
params.require(:post).permit(:title,  :slug,  :content)
end
end
Globalcode	
  – Open4education
Agora mãos a obra
já temos uma “API" em Rails, poderíamos ter o código em Sinatra que seria mais
leve, mas eu gosto do asset pipeline e assim fica mais fácil para um iniciante
Falta criar os componentes backbone para acessar o backend
Criar os componentes react para a UI
Globalcode	
  – Open4education
backbone.js
app/assets/javascripts/collections/posts.js
var Posts = Backbone.Collection.extend({
model: Post,
url: '/posts'
});
app/assets/jaascripts/models/post.js
var Post = Backbone.Model.extend({
});
Globalcode	
  – Open4education
blog.js.jsx
var Blog = React.createClass({
getInitialState: function(){
var posts = null;
var post = null;
if (this.props.collection) {
posts = new Posts(this.props.collection);
} else {
posts = new Posts();
posts.fetch({success:function(data){
this.forceUpdate();
}.bind(this)});
}
if (this.props.item) {
post = new Post(this.props.item);
} else {
post = new Post();
}
return {
collection: posts,
model: post,
editing: false
};
},
componentDidMount:function(){
this.router = new PostRouter({blog: this});
Backbone.history.start({pushState: true, root: "/"});
},
editModel:function(model){
this.setState({
model: model,
editing: true
})
},
viewModel:function(model){
this.setState({
model:  model,
editing:  false
});;
this.router.navigate("/posts/"  +  model.get("slug"),  {trigger:  true});;
},
newModel:function(){
this.setState({
model:  new  Post(),
editing:  true
})
},
render:  function   ()  {
if(this.state.editing)  {
return  (<div>
<div  id="blogList">
<PostList collection={this.state.collection}  viewModel={this.viewModel}  
newModel={this.newModel}/>
</div>
<div  id="blogPost">
<PostForm collection={this.state.collection}  model={this.state.model}  
viewModel={this.viewModel}/>
</div>
</div>);;
}else{
return  (<div>
<div  id="blogList">
<PostList collection={this.state.collection}  viewModel={this.viewModel}  
newModel={this.newModel}/>
</div>
<div  id="blogPost">
<PostView model={this.state.model}  editModel={this.editModel}/>
</div>
</div>);;
}
}
});;
Globalcode	
  – Open4education
post_list.js.jsx
var PostList = React.createClass({
componentDidMount: function () {
this.props.collection.on("change", function () {
this.forceUpdate()
}, this);
this.props.collection.on("reset", function () {
this.forceUpdate()
}, this);
},
componentWillUnmount: function () {
this.props.collection.off(null, null, this);
},
render: function () {
var users = this.props.collection.map(function (model) {
var viewModel = function () {
this.props.viewModel(model);
};
return (
<tr key={model.get("id")}>
<td><a href="#" onClick={viewModel.bind(this)}>{model.get("title")}</a></td>
<td>{new Date(model.get("created_at")).toDateString()}</td>
</tr>
);
}.bind(this));
return (
<div>
<table className="post-list">
<thead>
<tr>
<th>Post</th>
<th>Published</th>
</tr>
</thead>
<tbody>
{users}
</tbody>
</table>
<hr/>
<a href="#" onClick={this.props.newModel}>Create post</a>
</div>
);
}
});
Globalcode	
  – Open4education
post_view.js.jsx
var PostView = React.createClass({
editModel: function () {
this.props.editModel(this.props.model);
},
render: function () {
var innerLines = null;
if(this.props.model.get("content")) {
innerLines=_.map(this.props.model.get("content").split("n"), function (txt, idx) {
return <p key={idx}>{txt}</p>
});
}
return (
<div className="blog-post">
<h1><a href={this.props.model.get("slug")}>{this.props.model.get("title")}</a></h1>
<div className="post-body">
{innerLines}
</div>
<hr/>
<a href="#" onClick={this.editModel}>Edit post</a>
</div>
);
}
});
Globalcode	
  – Open4education
post_form.js.jsx
var PostForm = React.createClass({
saveModel: function () {
if (this.props.model.get("id")) {
this.props.model.save();
} else {
this.props.collection.create(this.props.model);
}
this.props.viewModel(this.props.model)
},
render: function () {
return (
<div className="blog-post">
<InputWithLabel model={this.props.model} label="Title" name="title" type="text"/>
<InputWithLabel model={this.props.model} label="Body" name="content" type="textarea"/>
<div className="form-field">
<button onClick={this.saveModel}>Save</button>
</div>
</div>
);
}
});
Globalcode	
  – Open4education
input_with_label.js.jsx
var InputWithLabel = React.createClass({
handleChange: function(event) {
this.props.model.set(this.props.name,event.target.value)
},
render: function() {
return <div className="form-field">
<label htmlFor={this.props.name}>{this.props.label}</label>
<div>
<input id={this.props.name} type={this.props.type} name={this.props.name} ref="input"
onChange={this.handleChange} value={this.props.model.get(this.props.name)}/>
</div>
</div>;
}
});
Globalcode	
  – Open4education
O que, quando, onde e por
que?
Muitas aplicações hoje em dia exigem um nível alto de interação com o usuário
Implementar isto usando bibliotecas mais baixo nível é muito fácil de causar
uma grande confusão do código (PHP alguem?)
Componentização evita duplicação de código e facilita a organização
Globalcode	
  – Open4education
Globalcode	
  – Open4education
indexação? performance?
renderização no servidor:
<%= react_component('Blog', {collection: @posts, item: @post},
{prerender: true}) %>
components.js
//= require underscore
//= require backbone
//= require_tree ./models
//= require_tree ./collections
//= require_tree ./components
Globalcode	
  – Open4education
Mas é só isto?
React-router
Backbone.Router
Flux - arquitetura JS usada pelo Facebook
Pré processamento com Gulp (sintaxe do ECMAScript 6 suportada)
Globalcode	
  – Open4education
Anúncio

Recomendados

TDC2015 Porto Alegre - Interfaces ricas com Rails e React.JS
TDC2015 Porto Alegre - Interfaces ricas com Rails e React.JS
Rodrigo Urubatan
 
React Native na globo.com
React Native na globo.com
Guilherme Heynemann Bruzzi
 
Mean Stack
Mean Stack
Bruno Catão
 
Curso de Grails
Curso de Grails
Bruno Nascimento
 
Curso de ReactJS
Curso de ReactJS
Gustavo Lopes
 
Web Offline
Web Offline
Bruno Catão
 
Construindo APIs RESTful com Spring
Construindo APIs RESTful com Spring
Mateus Malaquias
 
React + Flux (Alt)
React + Flux (Alt)
Cezar Luiz
 
Oficina groovy grails - infoway
Oficina groovy grails - infoway
Lucas Aquiles
 
Groovy grails
Groovy grails
Lucas Aquiles
 
Grails: O Java em Alta Produtividade
Grails: O Java em Alta Produtividade
Cleórbete Santos
 
ZF2 básico : Desenvolvendo um Blog com o Zend Framework 2
ZF2 básico : Desenvolvendo um Blog com o Zend Framework 2
Cezar Souza
 
Começando com Zend Framework 2
Começando com Zend Framework 2
Cezar Souza
 
WEB 2 - Aula 01 - 02.08
WEB 2 - Aula 01 - 02.08
Gilson Silva
 
Servlets e jsp
Servlets e jsp
Alan Oliveira
 
Java Web 3 - Servlets e JSP 1
Java Web 3 - Servlets e JSP 1
Eduardo Mendes
 
Desenvolvimento para a Web com CakePHP
Desenvolvimento para a Web com CakePHP
Marcelo Andrade
 
Angular js
Angular js
Bruno Catão
 
Zend Framework 1.11
Zend Framework 1.11
Cezar Souza
 
Java Web 2 - Ferramentas e configuração
Java Web 2 - Ferramentas e configuração
Eduardo Mendes
 
Beyond Ruby with NodeJS - RubyConf Brasil 2010
Beyond Ruby with NodeJS - RubyConf Brasil 2010
Emerson Macedo
 
Grails
Grails
Alex Guido
 
Aula Ruby
Aula Ruby
Felipe Gadelha Ruoso
 
Desenvolvimento web em java com JSP e Servlets
Desenvolvimento web em java com JSP e Servlets
Igo Coelho
 
Mini curso: Ionic Framework
Mini curso: Ionic Framework
Loiane Groner
 
Introdução ao vraptor
Introdução ao vraptor
Vitor Zachi Junior
 
Workshop Ruby on Rails dia 2 ruby-pt
Workshop Ruby on Rails dia 2 ruby-pt
Pedro Sousa
 
Desenvolvimento Front end (AngularJS e Bootstrap)
Desenvolvimento Front end (AngularJS e Bootstrap)
Julian Cesar
 
Rails Concerns and Turbolinks
Rails Concerns and Turbolinks
Nascenia IT
 
Efficient rails
Efficient rails
fabio perrella
 

Mais conteúdo relacionado

Mais procurados (20)

Oficina groovy grails - infoway
Oficina groovy grails - infoway
Lucas Aquiles
 
Groovy grails
Groovy grails
Lucas Aquiles
 
Grails: O Java em Alta Produtividade
Grails: O Java em Alta Produtividade
Cleórbete Santos
 
ZF2 básico : Desenvolvendo um Blog com o Zend Framework 2
ZF2 básico : Desenvolvendo um Blog com o Zend Framework 2
Cezar Souza
 
Começando com Zend Framework 2
Começando com Zend Framework 2
Cezar Souza
 
WEB 2 - Aula 01 - 02.08
WEB 2 - Aula 01 - 02.08
Gilson Silva
 
Servlets e jsp
Servlets e jsp
Alan Oliveira
 
Java Web 3 - Servlets e JSP 1
Java Web 3 - Servlets e JSP 1
Eduardo Mendes
 
Desenvolvimento para a Web com CakePHP
Desenvolvimento para a Web com CakePHP
Marcelo Andrade
 
Angular js
Angular js
Bruno Catão
 
Zend Framework 1.11
Zend Framework 1.11
Cezar Souza
 
Java Web 2 - Ferramentas e configuração
Java Web 2 - Ferramentas e configuração
Eduardo Mendes
 
Beyond Ruby with NodeJS - RubyConf Brasil 2010
Beyond Ruby with NodeJS - RubyConf Brasil 2010
Emerson Macedo
 
Grails
Grails
Alex Guido
 
Aula Ruby
Aula Ruby
Felipe Gadelha Ruoso
 
Desenvolvimento web em java com JSP e Servlets
Desenvolvimento web em java com JSP e Servlets
Igo Coelho
 
Mini curso: Ionic Framework
Mini curso: Ionic Framework
Loiane Groner
 
Introdução ao vraptor
Introdução ao vraptor
Vitor Zachi Junior
 
Workshop Ruby on Rails dia 2 ruby-pt
Workshop Ruby on Rails dia 2 ruby-pt
Pedro Sousa
 
Desenvolvimento Front end (AngularJS e Bootstrap)
Desenvolvimento Front end (AngularJS e Bootstrap)
Julian Cesar
 
Oficina groovy grails - infoway
Oficina groovy grails - infoway
Lucas Aquiles
 
Grails: O Java em Alta Produtividade
Grails: O Java em Alta Produtividade
Cleórbete Santos
 
ZF2 básico : Desenvolvendo um Blog com o Zend Framework 2
ZF2 básico : Desenvolvendo um Blog com o Zend Framework 2
Cezar Souza
 
Começando com Zend Framework 2
Começando com Zend Framework 2
Cezar Souza
 
WEB 2 - Aula 01 - 02.08
WEB 2 - Aula 01 - 02.08
Gilson Silva
 
Java Web 3 - Servlets e JSP 1
Java Web 3 - Servlets e JSP 1
Eduardo Mendes
 
Desenvolvimento para a Web com CakePHP
Desenvolvimento para a Web com CakePHP
Marcelo Andrade
 
Zend Framework 1.11
Zend Framework 1.11
Cezar Souza
 
Java Web 2 - Ferramentas e configuração
Java Web 2 - Ferramentas e configuração
Eduardo Mendes
 
Beyond Ruby with NodeJS - RubyConf Brasil 2010
Beyond Ruby with NodeJS - RubyConf Brasil 2010
Emerson Macedo
 
Desenvolvimento web em java com JSP e Servlets
Desenvolvimento web em java com JSP e Servlets
Igo Coelho
 
Mini curso: Ionic Framework
Mini curso: Ionic Framework
Loiane Groner
 
Workshop Ruby on Rails dia 2 ruby-pt
Workshop Ruby on Rails dia 2 ruby-pt
Pedro Sousa
 
Desenvolvimento Front end (AngularJS e Bootstrap)
Desenvolvimento Front end (AngularJS e Bootstrap)
Julian Cesar
 

Destaque (10)

Rails Concerns and Turbolinks
Rails Concerns and Turbolinks
Nascenia IT
 
Efficient rails
Efficient rails
fabio perrella
 
Real-Time Rails: Implementing WebSockets in Rails 5 with Action Cable
Real-Time Rails: Implementing WebSockets in Rails 5 with Action Cable
Sophie DeBenedetto
 
ウェブチップス勉強会 Action cable
ウェブチップス勉強会 Action cable
Yu Ito
 
What's new in Rails 5 - API Mode & Action Cable overview
What's new in Rails 5 - API Mode & Action Cable overview
Maxim Veksler
 
Real Time with Rails 5
Real Time with Rails 5
Lucas Renan
 
Ruby on Rails 5: Top 5 Features
Ruby on Rails 5: Top 5 Features
PhraseApp
 
Rails 5 – Amsterdam.rb – Uberous
Rails 5 – Amsterdam.rb – Uberous
Jeroen Visser
 
[Srijan Wednesday Webinar] Rails 5: What's in It for Me?
[Srijan Wednesday Webinar] Rails 5: What's in It for Me?
Srijan Technologies
 
What's New in Rails 5
What's New in Rails 5
Marko Sanković
 
Rails Concerns and Turbolinks
Rails Concerns and Turbolinks
Nascenia IT
 
Real-Time Rails: Implementing WebSockets in Rails 5 with Action Cable
Real-Time Rails: Implementing WebSockets in Rails 5 with Action Cable
Sophie DeBenedetto
 
ウェブチップス勉強会 Action cable
ウェブチップス勉強会 Action cable
Yu Ito
 
What's new in Rails 5 - API Mode & Action Cable overview
What's new in Rails 5 - API Mode & Action Cable overview
Maxim Veksler
 
Real Time with Rails 5
Real Time with Rails 5
Lucas Renan
 
Ruby on Rails 5: Top 5 Features
Ruby on Rails 5: Top 5 Features
PhraseApp
 
Rails 5 – Amsterdam.rb – Uberous
Rails 5 – Amsterdam.rb – Uberous
Jeroen Visser
 
[Srijan Wednesday Webinar] Rails 5: What's in It for Me?
[Srijan Wednesday Webinar] Rails 5: What's in It for Me?
Srijan Technologies
 
Anúncio

Semelhante a Interfaces ricas com Rails e React.JS @ Rubyconf 2015 (20)

TDC São Paulo 2015 - Interfaces Ricas com Rails e React.JS
TDC São Paulo 2015 - Interfaces Ricas com Rails e React.JS
Rodrigo Urubatan
 
JavaScript Model-View no Frontend
JavaScript Model-View no Frontend
Henrique Gogó
 
Backbone.js
Backbone.js
Filipe Giusti
 
Evento Front End SP - Organizando o Javascript
Evento Front End SP - Organizando o Javascript
Michel Ribeiro
 
Programando para programadores: Desafios na evolução de um Framework
Programando para programadores: Desafios na evolução de um Framework
Pablo Dall'Oglio
 
Evolução e futuro do uso de paradigmas no JavaScript
Evolução e futuro do uso de paradigmas no JavaScript
Jean Carlo Emer
 
Desenvolvimento ágil com Kohana framework
Desenvolvimento ágil com Kohana framework
Marcelo Rodrigo
 
Introduzindo StimulusJS: o novo Framework JavaScript para Ruby On Rails.
Introduzindo StimulusJS: o novo Framework JavaScript para Ruby On Rails.
Sergio Lima
 
Construindo portlets para IBM WebSphere Portal – Parte 2
Construindo portlets para IBM WebSphere Portal – Parte 2
rodrigoareis
 
Curso de Ruby on Rails - Aula 01
Curso de Ruby on Rails - Aula 01
Maurício Linhares
 
Aplicações rápidas para a Web com Django
Aplicações rápidas para a Web com Django
Freedom DayMS
 
Criando APIs com Node e TypeScript
Criando APIs com Node e TypeScript
Andre Baltieri
 
Workshop Node.js + MongoDB + Mongoose
Workshop Node.js + MongoDB + Mongoose
Luiz Duarte
 
Desenvolvimento de Sistemas Web com PHP Frameworks - 2019.1 - Aula 1
Desenvolvimento de Sistemas Web com PHP Frameworks - 2019.1 - Aula 1
Thyago Maia
 
Backbone.js + Rails - Front-end e back-end conectados
Backbone.js + Rails - Front-end e back-end conectados
Henrique Gogó
 
Php 05 Mvc
Php 05 Mvc
Regis Magalhães
 
Introducao ao Spring Web MVC
Introducao ao Spring Web MVC
Eder Magalhães
 
Solid
Solid
Jorge Oleques
 
Zend Framework
Zend Framework
Diego Tremper
 
Model View Controller
Model View Controller
Denis L Presciliano
 
TDC São Paulo 2015 - Interfaces Ricas com Rails e React.JS
TDC São Paulo 2015 - Interfaces Ricas com Rails e React.JS
Rodrigo Urubatan
 
JavaScript Model-View no Frontend
JavaScript Model-View no Frontend
Henrique Gogó
 
Evento Front End SP - Organizando o Javascript
Evento Front End SP - Organizando o Javascript
Michel Ribeiro
 
Programando para programadores: Desafios na evolução de um Framework
Programando para programadores: Desafios na evolução de um Framework
Pablo Dall'Oglio
 
Evolução e futuro do uso de paradigmas no JavaScript
Evolução e futuro do uso de paradigmas no JavaScript
Jean Carlo Emer
 
Desenvolvimento ágil com Kohana framework
Desenvolvimento ágil com Kohana framework
Marcelo Rodrigo
 
Introduzindo StimulusJS: o novo Framework JavaScript para Ruby On Rails.
Introduzindo StimulusJS: o novo Framework JavaScript para Ruby On Rails.
Sergio Lima
 
Construindo portlets para IBM WebSphere Portal – Parte 2
Construindo portlets para IBM WebSphere Portal – Parte 2
rodrigoareis
 
Curso de Ruby on Rails - Aula 01
Curso de Ruby on Rails - Aula 01
Maurício Linhares
 
Aplicações rápidas para a Web com Django
Aplicações rápidas para a Web com Django
Freedom DayMS
 
Criando APIs com Node e TypeScript
Criando APIs com Node e TypeScript
Andre Baltieri
 
Workshop Node.js + MongoDB + Mongoose
Workshop Node.js + MongoDB + Mongoose
Luiz Duarte
 
Desenvolvimento de Sistemas Web com PHP Frameworks - 2019.1 - Aula 1
Desenvolvimento de Sistemas Web com PHP Frameworks - 2019.1 - Aula 1
Thyago Maia
 
Backbone.js + Rails - Front-end e back-end conectados
Backbone.js + Rails - Front-end e back-end conectados
Henrique Gogó
 
Introducao ao Spring Web MVC
Introducao ao Spring Web MVC
Eder Magalhães
 
Anúncio

Mais de Rodrigo Urubatan (20)

Ruby code smells
Ruby code smells
Rodrigo Urubatan
 
Data science in ruby is it possible? is it fast? should we use it?
Data science in ruby is it possible? is it fast? should we use it?
Rodrigo Urubatan
 
Data science in ruby, is it possible? is it fast? should we use it?
Data science in ruby, is it possible? is it fast? should we use it?
Rodrigo Urubatan
 
2018 the conf put git to work - increase the quality of your rails project...
2018 the conf put git to work - increase the quality of your rails project...
Rodrigo Urubatan
 
2018 RubyHACK: put git to work - increase the quality of your rails project...
2018 RubyHACK: put git to work - increase the quality of your rails project...
Rodrigo Urubatan
 
TDC2017 - POA - Aprendendo a usar Xamarin para desenvolver aplicações moveis ...
TDC2017 - POA - Aprendendo a usar Xamarin para desenvolver aplicações moveis ...
Rodrigo Urubatan
 
Your first game with unity3d framework
Your first game with unity3d framework
Rodrigo Urubatan
 
Tdc Floripa 2017 - 8 falácias da programação distribuída
Tdc Floripa 2017 - 8 falácias da programação distribuída
Rodrigo Urubatan
 
Rubyconf2016 - Solving communication problems in distributed teams with BDD
Rubyconf2016 - Solving communication problems in distributed teams with BDD
Rodrigo Urubatan
 
resolvendo problemas de comunicação em equipes distribuídas com bdd
resolvendo problemas de comunicação em equipes distribuídas com bdd
Rodrigo Urubatan
 
vantagens e desvantagens de trabalhar remoto
vantagens e desvantagens de trabalhar remoto
Rodrigo Urubatan
 
Using BDD to Solve communication problems
Using BDD to Solve communication problems
Rodrigo Urubatan
 
Full Text Search com Solr, MySQL Full text e PostgreSQL Full Text
Full Text Search com Solr, MySQL Full text e PostgreSQL Full Text
Rodrigo Urubatan
 
Ruby para programadores java
Ruby para programadores java
Rodrigo Urubatan
 
Treinamento html5, css e java script apresentado na HP
Treinamento html5, css e java script apresentado na HP
Rodrigo Urubatan
 
Ruby on rails impressione a você mesmo, seu chefe e seu cliente
Ruby on rails impressione a você mesmo, seu chefe e seu cliente
Rodrigo Urubatan
 
Mini curso rails 3
Mini curso rails 3
Rodrigo Urubatan
 
Aplicações Hibridas com Phonegap e HTML5
Aplicações Hibridas com Phonegap e HTML5
Rodrigo Urubatan
 
Git presentation to some coworkers some time ago
Git presentation to some coworkers some time ago
Rodrigo Urubatan
 
Intrudução ao Behavior Driven Development (BDD) com Ruby on Rails
Intrudução ao Behavior Driven Development (BDD) com Ruby on Rails
Rodrigo Urubatan
 
Data science in ruby is it possible? is it fast? should we use it?
Data science in ruby is it possible? is it fast? should we use it?
Rodrigo Urubatan
 
Data science in ruby, is it possible? is it fast? should we use it?
Data science in ruby, is it possible? is it fast? should we use it?
Rodrigo Urubatan
 
2018 the conf put git to work - increase the quality of your rails project...
2018 the conf put git to work - increase the quality of your rails project...
Rodrigo Urubatan
 
2018 RubyHACK: put git to work - increase the quality of your rails project...
2018 RubyHACK: put git to work - increase the quality of your rails project...
Rodrigo Urubatan
 
TDC2017 - POA - Aprendendo a usar Xamarin para desenvolver aplicações moveis ...
TDC2017 - POA - Aprendendo a usar Xamarin para desenvolver aplicações moveis ...
Rodrigo Urubatan
 
Your first game with unity3d framework
Your first game with unity3d framework
Rodrigo Urubatan
 
Tdc Floripa 2017 - 8 falácias da programação distribuída
Tdc Floripa 2017 - 8 falácias da programação distribuída
Rodrigo Urubatan
 
Rubyconf2016 - Solving communication problems in distributed teams with BDD
Rubyconf2016 - Solving communication problems in distributed teams with BDD
Rodrigo Urubatan
 
resolvendo problemas de comunicação em equipes distribuídas com bdd
resolvendo problemas de comunicação em equipes distribuídas com bdd
Rodrigo Urubatan
 
vantagens e desvantagens de trabalhar remoto
vantagens e desvantagens de trabalhar remoto
Rodrigo Urubatan
 
Using BDD to Solve communication problems
Using BDD to Solve communication problems
Rodrigo Urubatan
 
Full Text Search com Solr, MySQL Full text e PostgreSQL Full Text
Full Text Search com Solr, MySQL Full text e PostgreSQL Full Text
Rodrigo Urubatan
 
Ruby para programadores java
Ruby para programadores java
Rodrigo Urubatan
 
Treinamento html5, css e java script apresentado na HP
Treinamento html5, css e java script apresentado na HP
Rodrigo Urubatan
 
Ruby on rails impressione a você mesmo, seu chefe e seu cliente
Ruby on rails impressione a você mesmo, seu chefe e seu cliente
Rodrigo Urubatan
 
Aplicações Hibridas com Phonegap e HTML5
Aplicações Hibridas com Phonegap e HTML5
Rodrigo Urubatan
 
Git presentation to some coworkers some time ago
Git presentation to some coworkers some time ago
Rodrigo Urubatan
 
Intrudução ao Behavior Driven Development (BDD) com Ruby on Rails
Intrudução ao Behavior Driven Development (BDD) com Ruby on Rails
Rodrigo Urubatan
 

Interfaces ricas com Rails e React.JS @ Rubyconf 2015

  • 1. Globalcode  – Open4education Interfaces  ricas  com  Rails  e  React.JS Rodrigo  Urubatan @urubatan
  • 2. Globalcode  – Open4education Quem? Programador desde 1997 Trabalha com Ruby na Brightwire Escreveu "Ruby On Rails: Desenvolvimento fácil e Rápido de aplicações web” Já trabalhou com diversas linguagens (C, C++, Delphi, PHP, ASP, ColdFusion, VisualBasic, C#, Python, Ruby, Assembly, …) Apaixonado por Agile e atualmente por trabalho remoto Patinador, Corredor, Ciclista e agora resolveu aprender Karate :D Pai de um Guri de 6 anos http://urubatan.com.br - Anda meio abandonado mas vai voltar http://sobrecodigo.com - idem
  • 3. Globalcode  – Open4education Objetivo (O blog mais feio do mundo!)
  • 4. Globalcode  – Open4education Objetivo Usar o Rails como backend da aplicação Toda a interação com o usuário será implementada no cliente Validações e regras de negócio serão implementadas no servidor (sim, eu poderia usar Sinatra mas sou preguiçoso)
  • 5. Globalcode  – Open4education Cuidado! Nesta palestra vamos falar de uma SPA (Single Page Application) Isto tem vantagens e desvantagens Melhora muito a interação com o usuário sem duplicação de código, já que o código de renderização fica todo no JS Piora muito a indexação da sua aplicação por buscadores (adeus SEO - ou não…)
  • 6. Globalcode  – Open4education Criando a aplicação Uma aplicação padrão Rails (rails new …) Gemfile updates gem 'backbone-on-rails' gem 'react-rails', github: 'reactjs/react-rails', ref: 'master' Environment update (development.rb para começar) config.react.variant = :development config.react.addons = true # defaults to false config.react.server_renderer = React::ServerRendering::SprocketsRenderer bundle install rails g react:install
  • 7. Globalcode  – Open4education Componentes Componentes javascript vão ficar em app/assets/javascript/components Backbone.js vai facilitar a comunicação cliente/servidor arquivos .js.jsx tem uma facilidade extra, são compilados pelo react-rails via asset pipeline e permitem adicionar HTML inline
  • 8. Globalcode  – Open4education Cadastrando um Usuário rails g scaffold post title:string slug:text content:text Apagar todas as views do post exceto index.html.erb Apagar todo o código de index.html.erb e mudar para: <%= react_component('Blog', {collection: @posts, item: @post}) %>
  • 9. Globalcode  – Open4education Alterações no controller Fazer todos os métodos retornarem json, mais ou menos assim (não é a melhor tecnica, mas boa o suficiente para o exemplo) class PostsController < ApplicationController before_action :set_post, only: [:show, :edit, :update, :destroy] def index @posts = Post.all end def show @posts = Post.all render :index end # GET /posts/new def new @post = Post.new render :index end # POST /posts # POST /posts.json def create @post = Post.new(post_params) respond_to do |format| if @post.save format.json { render json: @post, status: :created, location: @post } else format.json { render json: @post.errors, status: :unprocessable_entity } end end end #  PATCH/PUT  /posts/1 #  PATCH/PUT  /posts/1.json def update respond_to do  |format| if  @post.update(post_params) format.json {  render  json:  @user,  status:  :ok,  location:  @post  } else format.json {  render  json:  @post.errors,  status:  :unprocessable_entity } end end end #  DELETE  /posts/1 #  DELETE  /posts/1.json def destroy @post.destroy respond_to do  |format| format.json {  head  :no_content } end end private #  Use  callbacks  to  share  common  setup  or  constraints  between  actions. def set_post @post  =  Post.find_by(slug:  params[:id])  ||  Post.find(params[:id]) end #  Never  trust  parameters  from  the  scary  internet,  only  allow  the  white  list  through. def post_params params.require(:post).permit(:title,  :slug,  :content) end end
  • 10. Globalcode  – Open4education Agora mãos a obra já temos uma “API" em Rails, poderíamos ter o código em Sinatra que seria mais leve, mas eu gosto do asset pipeline e assim fica mais fácil para um iniciante Falta criar os componentes backbone para acessar o backend Criar os componentes react para a UI
  • 11. Globalcode  – Open4education backbone.js app/assets/javascripts/collections/posts.js var Posts = Backbone.Collection.extend({ model: Post, url: '/posts' }); app/assets/jaascripts/models/post.js var Post = Backbone.Model.extend({ });
  • 12. Globalcode  – Open4education blog.js.jsx var Blog = React.createClass({ getInitialState: function(){ var posts = null; var post = null; if (this.props.collection) { posts = new Posts(this.props.collection); } else { posts = new Posts(); posts.fetch({success:function(data){ this.forceUpdate(); }.bind(this)}); } if (this.props.item) { post = new Post(this.props.item); } else { post = new Post(); } return { collection: posts, model: post, editing: false }; }, componentDidMount:function(){ this.router = new PostRouter({blog: this}); Backbone.history.start({pushState: true, root: "/"}); }, editModel:function(model){ this.setState({ model: model, editing: true }) }, viewModel:function(model){ this.setState({ model:  model, editing:  false });; this.router.navigate("/posts/"  +  model.get("slug"),  {trigger:  true});; }, newModel:function(){ this.setState({ model:  new  Post(), editing:  true }) }, render:  function   ()  { if(this.state.editing)  { return  (<div> <div  id="blogList"> <PostList collection={this.state.collection}  viewModel={this.viewModel}   newModel={this.newModel}/> </div> <div  id="blogPost"> <PostForm collection={this.state.collection}  model={this.state.model}   viewModel={this.viewModel}/> </div> </div>);; }else{ return  (<div> <div  id="blogList"> <PostList collection={this.state.collection}  viewModel={this.viewModel}   newModel={this.newModel}/> </div> <div  id="blogPost"> <PostView model={this.state.model}  editModel={this.editModel}/> </div> </div>);; } } });;
  • 13. Globalcode  – Open4education post_list.js.jsx var PostList = React.createClass({ componentDidMount: function () { this.props.collection.on("change", function () { this.forceUpdate() }, this); this.props.collection.on("reset", function () { this.forceUpdate() }, this); }, componentWillUnmount: function () { this.props.collection.off(null, null, this); }, render: function () { var users = this.props.collection.map(function (model) { var viewModel = function () { this.props.viewModel(model); }; return ( <tr key={model.get("id")}> <td><a href="#" onClick={viewModel.bind(this)}>{model.get("title")}</a></td> <td>{new Date(model.get("created_at")).toDateString()}</td> </tr> ); }.bind(this)); return ( <div> <table className="post-list"> <thead> <tr> <th>Post</th> <th>Published</th> </tr> </thead> <tbody> {users} </tbody> </table> <hr/> <a href="#" onClick={this.props.newModel}>Create post</a> </div> ); } });
  • 14. Globalcode  – Open4education post_view.js.jsx var PostView = React.createClass({ editModel: function () { this.props.editModel(this.props.model); }, render: function () { var innerLines = null; if(this.props.model.get("content")) { innerLines=_.map(this.props.model.get("content").split("n"), function (txt, idx) { return <p key={idx}>{txt}</p> }); } return ( <div className="blog-post"> <h1><a href={this.props.model.get("slug")}>{this.props.model.get("title")}</a></h1> <div className="post-body"> {innerLines} </div> <hr/> <a href="#" onClick={this.editModel}>Edit post</a> </div> ); } });
  • 15. Globalcode  – Open4education post_form.js.jsx var PostForm = React.createClass({ saveModel: function () { if (this.props.model.get("id")) { this.props.model.save(); } else { this.props.collection.create(this.props.model); } this.props.viewModel(this.props.model) }, render: function () { return ( <div className="blog-post"> <InputWithLabel model={this.props.model} label="Title" name="title" type="text"/> <InputWithLabel model={this.props.model} label="Body" name="content" type="textarea"/> <div className="form-field"> <button onClick={this.saveModel}>Save</button> </div> </div> ); } });
  • 16. Globalcode  – Open4education input_with_label.js.jsx var InputWithLabel = React.createClass({ handleChange: function(event) { this.props.model.set(this.props.name,event.target.value) }, render: function() { return <div className="form-field"> <label htmlFor={this.props.name}>{this.props.label}</label> <div> <input id={this.props.name} type={this.props.type} name={this.props.name} ref="input" onChange={this.handleChange} value={this.props.model.get(this.props.name)}/> </div> </div>; } });
  • 17. Globalcode  – Open4education O que, quando, onde e por que? Muitas aplicações hoje em dia exigem um nível alto de interação com o usuário Implementar isto usando bibliotecas mais baixo nível é muito fácil de causar uma grande confusão do código (PHP alguem?) Componentização evita duplicação de código e facilita a organização
  • 19. Globalcode  – Open4education indexação? performance? renderização no servidor: <%= react_component('Blog', {collection: @posts, item: @post}, {prerender: true}) %> components.js //= require underscore //= require backbone //= require_tree ./models //= require_tree ./collections //= require_tree ./components
  • 20. Globalcode  – Open4education Mas é só isto? React-router Backbone.Router Flux - arquitetura JS usada pelo Facebook Pré processamento com Gulp (sintaxe do ECMAScript 6 suportada)