Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Rails ama o seu Front end

Rails ama o seu Front end

Lucas Mazza

August 29, 2013
Tweet

More Decks by Lucas Mazza

Other Decks in Programming

Transcript

  1. <% # app/views/products/index.html.erb %> <% content_for :head do %> <%

    # meta tags para a lista de produtos %> <% end %> <% # app/views/products/show.html.erb %> <% content_for :head do %> <% # meta tags para um produto %> <% end %>
  2. <%= render 'activities/feed' %> <%= render 'activities/feed', pagination: false %>

    <% # app/views/activities/_feed.html.erb %> <% pagination ||= true %> Valores padrão
  3. <%= render 'partial' %> <%= render 'partial', tagline: 'Rubyconf 2013'

    %> <% # app/views/things/_partial.html.erb %> <%= if defined?(tagline) %> <h2><%= tagline %></h2> <% end %> Locals opcionais
  4. <%= render 'partial' %> <%= render 'partial', tagline: 'Rubyconf 2013'

    %> <% # app/views/things/_partial.html.erb %> <%= if local_assigns.key?(:tagline) %> <h2><%= tagline %></h2> <% end %> Locals opcionais
  5. Decorator Pattern “(..) design pattern that allows behavior to be

    added to an individual object, (..), without affecting the behavior of other objects from the same class.” http://en.wikipedia.org/wiki/Decorator_pattern
  6. Presenter Pattern “(..) a class representation of the state of

    the view.” Jay Fields - http://blog.jayfields.com/2007/03/rails-presenter-pattern.html
  7. class ProductPresenter < SomePresenterGem attribute :name, :sku, :price, :photo, :category,

    :description, :id, :slug, :available?, :pretty_much_every_attribute_ever def created_at object.created_at.strftime('%A, %B %e') end def product_link helpers.link_to(name, object) end end
  8. class ProductPresenter < SomePresenterGem attribute :name, :sku, :price, :photo, :category,

    :description, :id, :slug, :available?, :pretty_much_every_attribute_ever def created_at object.created_at.strftime('%A, %B %e') end def product_link helpers.link_to(name, object) end end ಠ_ಠ
  9. “Presenters do add an additional layer, and thus more complexity.

    (...)” Jay Fields - http://blog.jayfields.com/2007/03/rails-presenter-pattern.html
  10. “(...) A presenter is not likely to be a automatic

    decision or standard. (...)” Jay Fields - http://blog.jayfields.com/2007/03/rails-presenter-pattern.html
  11. “(...) Presenters are generally introduced when actions are required to

    act upon various models or the data in the database needs to be manipulated in various ways before it is displayed in the view.” Jay Fields - http://blog.jayfields.com/2007/03/rails-presenter-pattern.html
  12. •Agregações complexas •Abstrações que ainda não existem • Navegações •

    Calendários • Gráficos • ‘Value Objects’ isolados
  13. calendar = EventsCalendar.new(8, 2013, events) calendar.month # => 'Agosto' calendar.days.each

    do |day, events| # 1 => [#<Event>, #<Event>] # ... end calendar.previous_month # => 07/2013 calendar.next_month # => 09/2013
  14. def lazy_image_tag(name, options = {}) # ... end # <img

    src='dot.gif' data-original='...'> def follow_button_to(user, options = {}, &block) # ... end # <a href='/users/123/follow' class='follow-btn'>...</a>
  15. “Generally speaking, it’s a good idea to keep your HTML

    in your templates and out of your helpers.” Ryan Singer - "What belongs in a helper method?" http://37signals.com/svn/posts/1108-what-belongs-in-a-helper-method
  16. “Helpers are useful when they hide implementation details that are

    irrelevant to your template, or when they allow you to abstract common template code to avoid repetition” Ryan Singer - "What belongs in a helper method?" http://37signals.com/svn/posts/1108-what-belongs-in-a-helper-method
  17. “If you find yourself generating a lot of HTML in

    a helper, think twice and try to keep as much HTML in your template as possible.” Ryan Singer - "What belongs in a helper method?" http://37signals.com/svn/posts/1108-what-belongs-in-a-helper-method
  18. $(document).on('submit', 'form', function(event) { event.preventDefault(); var form = $(this); $.ajax({

    type: form.attr('method'), url: form.attr('action'), data: form.serializeArray();
  19. $(document).on('submit', 'form', function(event) { event.preventDefault(); var form = $(this); $.ajax({

    type: form.attr('method'), url: form.attr('action'), data: form.serializeArray(); success: function() { },
  20. $(document).on('submit', 'form', function(event) { event.preventDefault(); var form = $(this); $.ajax({

    type: form.attr('method'), url: form.attr('action'), data: form.serializeArray(); success: function() { }, complete: function() { },
  21. $(document).on('submit', 'form', function(event) { event.preventDefault(); var form = $(this); $.ajax({

    type: form.attr('method'), url: form.attr('action'), data: form.serializeArray(); success: function() { }, complete: function() { }, error: function() { }
  22. $(document).on('submit', 'form', function(event) { event.preventDefault(); var form = $(this); $.ajax({

    type: form.attr('method'), url: form.attr('action'), data: form.serializeArray(); success: function() { }, complete: function() { }, error: function() { } });
  23. $(document).on('submit', 'form', function(event) { event.preventDefault(); var form = $(this); $.ajax({

    type: form.attr('method'), url: form.attr('action'), data: form.serializeArray(); success: function() { }, complete: function() { }, error: function() { } }); });
  24. <%= form_for @user, remote: true do |form| %> <%= form.submit

    'Cadastrar!', data: { disable_with: 'Aguarde..' } %> <% end %> <%= link_to 'Apagar', @user, remote: true, method: :delete, data: { confirm: 'Tem certeza?' } %> data-* goodies
  25. Abstraia o trabalho sujo de fazer requisições Ajax Assim como

    o Active Record abstrai consultas no seu banco.
  26. Abstraia o trabalho sujo de fazer requisições Ajax Escreva testes

    para os eventos, não para a interação de rede.
  27. •Reaproveitamento da sua camada inteira de views, helpers & cia.

    •Lógica cacheada no client. •Eventos testáveis.
  28. $(document).on('ajax:success', function(event, html, status, xhr) { var redirectTo = xhr.getResponseHeader('Location');

    if(redirectTo) { window.location = redirectTo; } }); render nothing: true ou head :created, location: '...'
  29. jquery-rails jquery-ui-rails twitter-bootstrap-rails less-rails-bootstrap chosen-rails font-awesome-sass- rails modernizr-rails select2-rails fancybox-rails

    underscore-rails bootstrap-sass-rails requirejs-rails facebox-rails formalize-rails momentjs-rails zero-clipboard-rails skeleton-rails mini-bootstrap-rails html5shiv-rails zepto-rails bootstrap-tooltip-rails kube-rails ETooMuchGems
  30. // bower.json { "name": "my-rails-app", "version": "0.0.0", "ignore": [ "**/.*",

    "node_modules", "bower_components", "test", "tests" ], "dependencies": { "jquery-pjax": "1.7.3", "momentjs": "2.1.0", "module": "git://github.com/fnando/module.git" } }
  31. $ bower install ... bower module#* install module#518331e7d5 bower jquery-pjax#1.7.3

    install jquery-pjax#1.7.3 bower momentjs#2.1.0 install momentjs#2.1.0 bower jquery#>=1.8 install jquery#2.0.3 module#518331e7d5 vendor/assets/components/module jquery-pjax#1.7.3 vendor/assets/components/jquery-pjax └── jquery#2.0.3 momentjs#2.1.0 vendor/assets/components/momentjs jquery#2.0.3 vendor/assets/components/jquery
  32. class EventsController < ApplicationController include ActionController::Live def subscribe response.headers['Content-Type'] =

    'text/event-stream' loop do response.stream.write 'data: WHATSUP!\n\n' sleep 5 end rescue IOError # Connection closed ensure response.stream.close end end ActionController::Live
  33. class EventsController < ApplicationController include ActionController::Live def subscribe response.headers['Content-Type'] =

    'text/event-stream' sse = SSE.new(response.stream) loop do sse.write('WHATSUP!') sleep 5 end rescue IOError # Connection closed ensure sse.close end end Rails 4.1
  34. # config/application.rb config.action_dispatch. default_headers['Access-Control-Allow-Credentials'] = 'true' config.action_dispatch. default_headers['Access-Control-Allow-Origin'] = '*'

    config.action_dispatch. default_headers['Access-Control-Expose-Headers'] = 'X-My-Header' config.action_dispatch. default_headers['Access-Control-Allow-Headers'] = 'X-Request-Header'
  35. “Activating CSP in a Rails app is trivial since it's

    just a simple header. You don't need any separate libraries; a simple before filter should do.” https://github.com/blog/1477-content-security-policy class ApplicationController < ActionController::Base before_filter :set_csp def set_csp response.headers['Content-Security-Policy'] = "default-src *; script-src https://assets.example.com; style-src https:// assets.example.com" end end
  36. .mobile views Mustache Cache Sweepers Compass AS::Notifications Pjax Jasmine Bourbon

    Turbolinks Peek Simple Form i18n-js AssetSync MailView