Your SlideShare is downloading. ×
0
The Rails Way
The Rails Way
The Rails Way
The Rails Way
The Rails Way
The Rails Way
The Rails Way
The Rails Way
The Rails Way
The Rails Way
The Rails Way
The Rails Way
The Rails Way
The Rails Way
The Rails Way
The Rails Way
The Rails Way
The Rails Way
The Rails Way
The Rails Way
The Rails Way
The Rails Way
The Rails Way
The Rails Way
The Rails Way
The Rails Way
The Rails Way
The Rails Way
The Rails Way
The Rails Way
The Rails Way
The Rails Way
The Rails Way
The Rails Way
The Rails Way
The Rails Way
The Rails Way
The Rails Way
The Rails Way
The Rails Way
The Rails Way
The Rails Way
The Rails Way
The Rails Way
The Rails Way
The Rails Way
The Rails Way
The Rails Way
The Rails Way
The Rails Way
The Rails Way
The Rails Way
The Rails Way
The Rails Way
The Rails Way
The Rails Way
The Rails Way
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

The Rails Way

2,779

Published on

Published in: Technology
0 Comments
2 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
2,779
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
25
Comments
0
Likes
2
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. The Rails WayApproach to modern web applications with Rails 3.2
  • 2. The Performance Golden Rule80% of end-users response time isdownloading all the assets.
  • 3. The Rails Way to managingassets: HTTP Streaming The Assets Pipeline
  • 4. Assets Pipeline● Assets concatenation● Assets minification● Support for high-level languages ○ CoffeeScript ○ SASS● Assets fingerprinting
  • 5. Syntactically Awesome Stylesheets$blue: #3bbfce;$margin: 16px;.content-navigation { border-color: $blue; color: darken($blue, 9%);}.border { padding: $margin / 2; margin: $margin / 2; border-color: $blue;}
  • 6. CoffeeScriptclass ProfileCompetences extends Backbone.View tagName: ul className: inputs-select initialize: -> @collection.on(reset, @render, this) render: -> competences = @collection.competences() _.each competences, (competence) => view = new AutosaveSelectOption(model: @model, dict: competence) $(@el).append(view.render().el) this
  • 7. Serving Static Assets Rails by default doesnt serve static assets in production environment.
  • 8. Deploymentict-ref-cloud/ current -> ~/ict-ref-cloud/releases/20120904134910 releases/ 20120904134910/ app/ config/ database.yml -> ~/ict-ref-cloud/shared/config/database.yml public/ assets -> ~/ict-ref-cloud/shared/assets shared/ assets/ application-8e3bd046319a574dc48990673b1a4dd9.js application-8e3bd046319a574dc48990673b1a4dd9.js.gz application.css application.css.gz config/ database.yml
  • 9. Deployment nginx ~/ict-ref-cloud/current/public/tmp/unicorn.ict-ref-cloud.sock unicorn ~/ict-ref-cloud/current
  • 10. OWASP Top Ten Security Risk 1. Injection 2. Cross Site Scripting 3. Broken Authentication and Session Management 4. Insecure Direct Object Reference 5. Cross Site Request Forgery 6. Security Misconfiguration 7. Insecure Cryptographic Storage 8. Failure To Restrict URL Access 9. Insufficient Transport Layer Protection10. Unvalidated Redirects and Forwards
  • 11. OWASP Top Ten Security Risk 1. Injection 2. Cross Site Scripting 3. Broken Authentication and Session Management 4. Insecure Direct Object Reference 5. Cross Site Request Forgery 6. Security Misconfiguration 7. Insecure Cryptographic Storage 8. Failure To Restrict URL Access 9. Insufficient Transport Layer Protection10. Unvalidated Redirects and Forwards Problems related specifically to view layer.
  • 12. The Rails Way to security: CSRF protection XSS protection
  • 13. Cross Site Request Forgery/app/controllers/application_controller.rbclass ApplicationController < ActionController::Base protect_from_forgeryend/app/views/layouts/application.html.erb<head> <%= csrf_meta_tags %></head><meta content="authenticity_token" name="csrf-param"><meta content="KklMulGyhEfVztqfpMn5nRYc7zv+tNYb3YovBwOhTic=" name="csrf-token">
  • 14. Cross Site Scripting<div id="comments"> <% @post.comments.each do |comment| %> <div class="comment"> <h4><%= comment.author %> says:</h4> <p><%= comment.content %></p> </div> <% end %></div><%# Insecure! %><%= raw product.description %>
  • 15. The Rails Way to routing: Non-Resourceful routes Resourceful routes SEO friendly URLs
  • 16. Non-Resourceful Routesmatch products/:id => products#showGET /products/10post products => products#createPOST /productsnamespace :api do put products/:id => api/products#updateendPUT /api/products/10
  • 17. Non-Resourceful Routesmatch photos/show => photos#show, :via => [:get, :post]match photos/:id => photos#show, :constraints => { :id => /[A-Z]d{5}/ }match "photos", :constraints => { :subdomain => "admin" }match "/stories/:name" => redirect("/posts/%{name}")match books/*section/:title => books#showroot :to => pages#main
  • 18. Resourceful Routesresources :photosget /photos => photos#indexget /photos/new => photos#newpost /photos => photos#createget /photos/:id => photos#showget /photos/:id/edit => photos#editput /photos/:id => photo#updatedelete /photos/:id => photo#destroy
  • 19. Resourceful Routesresource :profileget /profile/new => profiles#newpost /profile => profiles#createget /profile => profiles#showget /profile/edit => profiles#editput /profile => profile#updatedelete /profile => profile#destroy
  • 20. Named Routes<%= link_to Profile, profile_path %>=> <a href="/profile">Profile</a><%= link_to Preview, @photo %>=> <a href="/photo/10">Preview</a>
  • 21. SEO Friendy URLs <%= link_to product.name, product %> Will generate /products/14-foo-bar /products/14-foo-bar "/products/:id" => "products#show" { :id => "14-foo-bar" } class Product < ActiveRecord::Base def to_param "#{id}-#{name.parametrize}" end Product.find(params[:id]) end Will call to_i Product.find(14)Example from: http://www.codeschool.com/courses/rails-best-practices
  • 22. The Rails Way to viewrendering: Response rendering Structuring Layouts AJAX
  • 23. Response Rendering/app /app /controllers /views products_controller.rb /products users_controller.rb index.html.erb show.html.erb /users index.html.erb new.html.erb
  • 24. Response Renderingclass UsersController < ApplicationController def new @user = User.new new.html.erb end def create @user = User.new(params[:user]) if @user.save redirect_to :action => :show show.html.erb else render :new new.html.erb end endend
  • 25. Rendering Responserender :editrender :action => :editrender editrender edit.html.erbrender :template => products/editrender products/editrender :file => /path/to/filerender /path/to/file
  • 26. Rendering Responserender :inline => <p><%= @comment.content %></p>render :text => OKrender :json => @productrender :xml => @productrender :js => "alert(Hello Rails);"render :status => 500render :status => :forbiddenrender :nothing => true, :status => :created
  • 27. Content Negotiationrespond_to do |format| format.html format.json { render :json => @product } format.jsend
  • 28. Content Negotiationclass ProductsController < ApplicationController respond_to :html, :json, :js def edit respond_with Product.find(params[:id]) end def update respond_with Product.update(params[:id], params[:product]) endend
  • 29. Structuring Layout/app /views /layouts application.html.erb (default) users.html.erb (UsersController) public.html.erb (layout public)
  • 30. Structuring Layout<!DOCTYPE html><head> <title>User <%= yield :title %></title></head><html> <body> <%= yield %> </body></html>
  • 31. Structuring Layout<% content_for :title, @post.title %><div id="post"> <h2><%= @post.title %></h2> <div><%= @post.content %></div></div>
  • 32. View Helpersmodule ApplicationHelper def title(title) content_for :title, title endend
  • 33. View Helpers<% title @post.title %><div id="post"> <h2><%= @post.title %></h2> <div><%= @post.content %></div></div>
  • 34. Partials/app /views /products _form.html.erb _product.html.erb index.html.erb edit.html.erb new.html.erb
  • 35. Partials/app/views/products/_product.html.erb<div class="product"> <h2><%= product.name %></h2> <p><%= product.description %></p></div> Partial parameter
  • 36. Partials<h1>Products</h1><% @products.each do |product| %> <% render products/product, :product => product %><% end %>
  • 37. Partials<h1>Products</h1><% @products.each do |product| %> <% render product %><% end %>
  • 38. Partials<h1>Products</h1><% render @products %>
  • 39. Partials/app/views/products/_form.html.erb<%= form_for @user do |f| %> <div class="input"> <%= f.label :name %> <%= f.text_field :name %> </div> <div class="input"> <%= f.label :description %> <%= f.text_area :description %> </div> <div class="actions"> <%= f.submit %> </div><% end %>
  • 40. Partials../products/new.html.erb ../products/edit.html.erb<h1>New Product</h1> <h1>Edit Product</h1><div id="form"> <div id="form"> <% render form %> <% render form %></div> </div>
  • 41. AJAX/app/views/products/_form.html.erb<%= form_for @user, :remote => true do |f| %> <div class="input"> <%= f.label :name %> <%= f.text_field :name %> </div> <div class="input"> <%= f.label :description %> <%= f.text_area :description %> </div> <div class="actions"> <%= f.submit %> </div><% end %>
  • 42. AJAX/app/controllers/products_controller.rbclass ProductsController < ApplicationController def create @product = Product.new(params[:product]) respond_to do |format| if @product.save format.html { redirect_to @product } else format.html { render :action => new } format.js end end endend
  • 43. AJAX/app/views/products/create.js.erb$(#form).html("<%= escape_javascript(render form) %>");
  • 44. AJAX/app/views/products/index.html.erb<%= link_to "Delete", product, method: :delete, remote: true %><a href="/products/1" data-method="delete" data-remote="true" rel="nofollow">Delete</a> (Rails is using unobtrusive javascript technique)/app/views/products/destroy.js.erb$("#<%= dom_id @product %>").fadeOut();
  • 45. The Rails Way to caching: Basic Caching Memoization
  • 46. Page Cachingclass ProductsController < ActionController caches_page :index def index @products = Product.all end def create expire_page :action => :index endendPage caching wont work with filters.
  • 47. Action Cachingclass ProductsController < ActionController before_filter :authenticate_user! caches_action :index def index @products = Product.all end def create expire_action :action => :index endend
  • 48. Fragment Caching<% cache do %> All available products: <% @products.each do |p| %> <%= link_to p.name, product_url(p) %> <% end %><% end %>expire_fragment( :controller => products, :action => recent, :action_suffix => all_products)
  • 49. Sweepersclass ProductSweeper < ActionController::Caching::Sweeper observe Product def after_create(product) # Expire the index page now that we added a new product expire_page(:controller => products, :action => index) # Expire a fragment expire_fragment(all_available_products) endend
  • 50. Conditional GET supportclass ProductsController < ApplicationController def show @product = Product.find(params[:id]) if stale?(:last_modified => @product.updated_at.utc, :etag => @product) respond_to do |format| # ... normal response processing end end endend
  • 51. Memoizationclass City < ActiveRecord::Base attr_accesible :name, :zip, :lat, :lon def display_name @display_name ||= "#@zip #@name" endend
  • 52. The Rails Way to solvetypical problems: N+1 Problem Fetching object in batches
  • 53. N+1 Problemclass User def recent_followers self.followers.recent.collect do |f| f.user.name end endendSelect followers where user_id=1 Select user where id=2 Select user where id=3 Select user where id=4 Select user where id=5Source: http://www.codeschool.com/courses/rails-best-practices
  • 54. N+1 Problemclass User def recent_followers self.followers.recent.includes(:user).collect do |f| f.user.name end endendSelect followers where user_id=1 Select users where user_id in (2,3,4,5)Bullet Gem:https://github.com/flyerhzm/bulletSource: http://www.codeschool.com/courses/rails-best-practices
  • 55. Fetching objects in JavaList<Tweet> tweets = tweetDao.findAllForUser(user);for (Tweet tweet : tweets) { // ...}for (Tweet tweet : user.getTweets()) { // ...}
  • 56. Fetching objects in RailsTweet.where(user: user).find_each do |tweet| # ...enduser.tweets.find_each(batch_size: 5000) do |tweet| # ...endBy default pulls batches of 1,000 at a time
  • 57. Try Rails!

×