• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
Rails Best Practices
 

Rails Best Practices

on

  • 1,456 views

 

Statistics

Views

Total Views
1,456
Views on SlideShare
1,453
Embed Views
3

Actions

Likes
2
Downloads
23
Comments
0

2 Embeds 3

https://twitter.com 2
https://www.linkedin.com 1

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    Rails Best Practices Rails Best Practices Presentation Transcript

    • Rails Best PracticesFriday, August 31, 12
    • Why best practices?Friday, August 31, 12
    • Why best practices? 01 MaintainabilityFriday, August 31, 12
    • Why best practices? 01 Maintainability 02 DRY codeFriday, August 31, 12
    • Why best practices? 01 Maintainability 02 DRY code 03 Better delegationFriday, August 31, 12
    • Why best practices? 01 Maintainability 02 DRY code 03 Better delegation 04 It just worksFriday, August 31, 12
    • Fat models, skinny controllersFriday, August 31, 12
    • Fat models, skinny controllers class TweetsController < ApplicationController def index if params[:search].present? @tweets = Tweet.all else @tweets = Tweet.where("content LIKE ?", "%#{params[:search]}%") end end endFriday, August 31, 12
    • Fat models, skinny controllers class TweetsController < ApplicationController def index if params[:search].present? @tweets = Tweet.all else @tweets = Tweet.where("content LIKE ?", "%#{params[:search]}%") end end endFriday, August 31, 12
    • Fat models, skinny controllers class TweetsController < ApplicationController def index if params[:search].present? @tweets = Tweet.all else @tweets = Tweet.where("content LIKE ?", "%#{params[:search]}%") end end end class TweetsController < ApplicationController def index @tweets = Tweet.search(params) end endFriday, August 31, 12
    • Fat models, skinny controllers class TweetsController < ApplicationController def index if params[:search].present? @tweets = Tweet.all else @tweets = Tweet.where("content LIKE ?", "%#{params[:search]}%") end end end class TweetsController < ApplicationController def self.search(params= {}) if params[:search].present def index where("content LIKE ?", "%#{params[:search]}%") @tweets = Tweet.search(params) else end all end end endFriday, August 31, 12
    • Fat models, skinny controllers class TweetsController < ApplicationController def index if params[:search].present? @tweets = Tweet.all else @tweets = Tweet.where("content LIKE ?", "%#{params[:search]}%") end end end class TweetsController < ApplicationController def self.search(params= {}) if params[:search].present def index where("content LIKE ?", "%#{params[:search]}%") @tweets = Tweet.search(params) else end all end end endFriday, August 31, 12
    • Scope it outFriday, August 31, 12
    • Scope it out class UsersController < ApplicationController def show @user = User.find(params[:id]) @tweets = @user.tweets.where("retweets_count > 5").order(created_at DESC).limit(5) end endFriday, August 31, 12
    • Scope it out class UsersController < ApplicationController def show @user = User.find(params[:id]) @tweets = @user.tweets.where("retweets_count > 5").order(created_at DESC).limit(5) end endFriday, August 31, 12
    • Scope it out class UsersController < ApplicationController def show @user = User.find(params[:id]) @tweets = @user.tweets.where("retweets_count > 5").order(created_at DESC).limit(5) end endFriday, August 31, 12
    • Scope it out class UsersController < ApplicationController def show @user = User.find(params[:id]) @tweets = @user.tweets.where("retweets_count > 5").order(created_at DESC).limit(5) end end class UsersController < ApplicationController def show @user = User.find(params[:id]) @tweets = @user.tweets.with_many_retweets.recent.limit(5) end endFriday, August 31, 12
    • Scope it out class UsersController < ApplicationController def show @user = User.find(params[:id]) @tweets = @user.tweets.where("retweets_count > 5").order(created_at DESC).limit(5) end end class UsersController < ApplicationController def show @user = User.find(params[:id]) @tweets = @user.tweets.with_many_retweets.recent.limit(5) end endFriday, August 31, 12
    • Scope it out class UsersController < ApplicationController def show @user = User.find(params[:id]) @tweets = @user.tweets.where("retweets_count > 5").order(created_at DESC).limit(5) end end class Tweet < ActiveRecord::Base class UsersController < ApplicationController attr_accessible :content, :user_id def show belongs_to :user @user = User.find(params[:id]) @tweets = @user.tweets.with_many_retweets.recent.limit(5) scope :recent, order(created_at DESC) end scope :with_many_retweets, where("retweets_count > 5") end endFriday, August 31, 12
    • Scope it out class UsersController < ApplicationController def show @user = User.find(params[:id]) @tweets = @user.tweets.where("retweets_count > 5").order(created_at DESC).limit(5) end end class Tweet < ActiveRecord::Base class UsersController < ApplicationController attr_accessible :content, :user_id def show belongs_to :user @user = User.find(params[:id]) @tweets = @user.tweets.with_many_retweets.recent.limit(5) scope :recent, order(created_at DESC) end scope :with_many_retweets, where("retweets_count > 5") end endFriday, August 31, 12
    • SQL InjectionFriday, August 31, 12
    • SQL Injection User.where("name = #{params[:search]}")Friday, August 31, 12
    • SQL Injection User.where("name = #{params[:search]}")Friday, August 31, 12
    • SQL Injection User.where("name = #{params[:search]}") User.where("name = ?", "#{params[:search]}")Friday, August 31, 12
    • SQL Injection User.where("name = #{params[:search]}") User.where("name = ?", "#{params[:search]}") User.where(:name => params[:search])Friday, August 31, 12
    • SQL Injection User.where("name = #{params[:search]}") User.where("name = ?", "#{params[:search]}") User.where(:name => params[:search]) User.where("username = :login OR email = :login", {:login => params[:login]})Friday, August 31, 12
    • Model without DB && REST #encoding: utf-8 class ContactsController < ApplicationController class Contact def new include ActiveModel::Validations @contact = Contact.new include ActiveModel::Conversion end attr_accessor :name, :email, :message def create validates :name, :email, :company, :reason, @contact = Contact.new(params[:contact]) :message, :presence => true if @contact.valid? ContactMailer.contact_message(@contact).deliver def initialize(attributes = {}) redirect_to root_path, :notice => "Sweet!" attributes.each do |name, value| else send("#{name}=", value) render :new end end end end end def persisted? false end end REST: Don’t be too deep - /users/1/tweets/ 3/comments/2 Not using REST is ok tooFriday, August 31, 12
    • Model without DB && REST #encoding: utf-8 class ContactsController < ApplicationController class Contact def new include ActiveModel::Validations @contact = Contact.new include ActiveModel::Conversion end attr_accessor :name, :email, :message def create validates :name, :email, :company, :reason, @contact = Contact.new(params[:contact]) :message, :presence => true if @contact.valid? ContactMailer.contact_message(@contact).deliver def initialize(attributes = {}) redirect_to root_path, :notice => "Sweet!" attributes.each do |name, value| else send("#{name}=", value) render :new end end end end end def persisted? false end end REST: Don’t be too deep - /users/1/tweets/ 3/comments/2 Not using REST is ok tooFriday, August 31, 12
    • Model without DB && REST #encoding: utf-8 class ContactsController < ApplicationController class Contact def new include ActiveModel::Validations @contact = Contact.new include ActiveModel::Conversion end attr_accessor :name, :email, :message def create validates :name, :email, :company, :reason, @contact = Contact.new(params[:contact]) :message, :presence => true if @contact.valid? ContactMailer.contact_message(@contact).deliver def initialize(attributes = {}) redirect_to root_path, :notice => "Sweet!" attributes.each do |name, value| else send("#{name}=", value) render :new end end end end end def persisted? false end end REST: Don’t be too deep - /users/1/tweets/ 3/comments/2 Not using REST is ok tooFriday, August 31, 12
    • Model without DB && REST #encoding: utf-8 class ContactsController < ApplicationController class Contact def new include ActiveModel::Validations @contact = Contact.new include ActiveModel::Conversion end attr_accessor :name, :email, :message def create validates :name, :email, :company, :reason, @contact = Contact.new(params[:contact]) :message, :presence => true if @contact.valid? ContactMailer.contact_message(@contact).deliver def initialize(attributes = {}) redirect_to root_path, :notice => "Sweet!" attributes.each do |name, value| else send("#{name}=", value) render :new end end end end end def persisted? false end end REST: Don’t be too deep - /users/1/tweets/ 3/comments/2 Not using REST is ok tooFriday, August 31, 12
    • N+1 Queries are not coolFriday, August 31, 12
    • N+1 Queries are not cool def recent_followers self.followers.recent.collect {|f| f.user.name }.to_sentence endFriday, August 31, 12
    • N+1 Queries are not cool def recent_followers self.followers.recent.collect {|f| f.user.name }.to_sentence endFriday, August 31, 12
    • N+1 Queries are not cool def recent_followers self.followers.recent.collect {|f| f.user.name }.to_sentence endFriday, August 31, 12
    • N+1 Queries are not cool def recent_followers self.followers.recent.collect {|f| f.user.name }.to_sentence end => “Edo, Lentes, Javi”Friday, August 31, 12
    • N+1 Queries are not cool def recent_followers self.followers.recent.collect {|f| f.user.name }.to_sentence end => “Edo, Lentes, Javi” Select followers where user_id = 1 Select user where id=2 Select user where id=3 Select user where id=4 Select user where id=5 5 fat queriesFriday, August 31, 12
    • N+1 Queries are not cool def recent_followers self.followers.recent.collect {|f| f.user.name }.to_sentence end => “Edo, Lentes, Javi” Select followers where user_id = 1 Select user where id=2 Select user where id=3 Select user where id=4 Select user where id=5 5 fat queriesFriday, August 31, 12
    • N+1 Queries are not coolFriday, August 31, 12
    • N+1 Queries are not cool def recent_followers self.followers.recent.includes(:user).collect {|f| f.user.name }.to_sentence endFriday, August 31, 12
    • N+1 Queries are not cool def recent_followers self.followers.recent.includes(:user).collect {|f| f.user.name }.to_sentence end => “Edo, Lentes, Javi”Friday, August 31, 12
    • N+1 Queries are not cool def recent_followers self.followers.recent.includes(:user).collect {|f| f.user.name }.to_sentence end => “Edo, Lentes, Javi” Select followers where user_id = 1Friday, August 31, 12
    • N+1 Queries are not cool def recent_followers self.followers.recent.includes(:user).collect {|f| f.user.name }.to_sentence end => “Edo, Lentes, Javi” Select followers where user_id = 1 Select users where user_id in (2,3,4,5) 2 queriesFriday, August 31, 12
    • N+1 Queries are not cool def recent_followers self.followers.recent.includes(:user).collect {|f| f.user.name }.to_sentence end => “Edo, Lentes, Javi” Select followers where user_id = 1 Select users where user_id in (2,3,4,5) 2 queries Check out the bullet gem at: h"ps://github.com/flyerhzm/bulletFriday, August 31, 12
    • Counter cache FTW!Friday, August 31, 12
    • Counter cache FTW! <%= pluralize @user.tweets.length, tweet %>Friday, August 31, 12
    • Counter cache FTW! 1. Select all tweets from user <%= pluralize @user.tweets.length, tweet %> 2. Populate an array of objects 3. Call length on the arrayFriday, August 31, 12
    • Counter cache FTW! 1. Select all tweets from user <%= pluralize @user.tweets.length, tweet %> 2. Populate an array of objects 3. Call length on the arrayFriday, August 31, 12
    • Counter cache FTW! 1. Select all tweets from user <%= pluralize @user.tweets.length, tweet %> 2. Populate an array of objects 3. Call length on the array <%= pluralize @user.tweets.count, tweet %>Friday, August 31, 12
    • Counter cache FTW! 1. Select all tweets from user <%= pluralize @user.tweets.length, tweet %> 2. Populate an array of objects 3. Call length on the array <%= pluralize @user.tweets.count, tweet %> 1. Select all tweets from user 2. Do count query for tweetsFriday, August 31, 12
    • Counter cache FTW! 1. Select all tweets from user <%= pluralize @user.tweets.length, tweet %> 2. Populate an array of objects 3. Call length on the array <%= pluralize @user.tweets.count, tweet %> 1. Select all tweets from user 2. Do count query for tweetsFriday, August 31, 12
    • Counter cache FTW! 1. Select all tweets from user <%= pluralize @user.tweets.length, tweet %> 2. Populate an array of objects 3. Call length on the array <%= pluralize @user.tweets.count, tweet %> 1. Select all tweets from user 2. Do count query for tweetsFriday, August 31, 12
    • Counter cache FTW! 1. Select all tweets from user <%= pluralize @user.tweets.length, tweet %> 2. Populate an array of objects 3. Call length on the array <%= pluralize @user.tweets.count, tweet %> 1. Select all tweets from user 2. Do count query for tweets <%= pluralize @user.tweets.size, tweet %>Friday, August 31, 12
    • Counter cache FTW! 1. Select all tweets from user <%= pluralize @user.tweets.length, tweet %> 2. Populate an array of objects 3. Call length on the array <%= pluralize @user.tweets.count, tweet %> 1. Select all tweets from user 2. Do count query for tweets <%= pluralize @user.tweets.size, tweet %>Friday, August 31, 12
    • Counter cache FTW! 1. Select all tweets from user <%= pluralize @user.tweets.length, tweet %> 2. Populate an array of objects 3. Call length on the array <%= pluralize @user.tweets.count, tweet %> 1. Select all tweets from user 2. Do count query for tweets <%= pluralize @user.tweets.size, tweet %> 1. Select all tweets from userFriday, August 31, 12
    • Counter cache FTW! 1. Select all tweets from user <%= pluralize @user.tweets.length, tweet %> 2. Populate an array of objects 3. Call length on the array <%= pluralize @user.tweets.count, tweet %> 1. Select all tweets from user 2. Do count query for tweets <%= pluralize @user.tweets.size, tweet %> 1. Select all tweets from userFriday, August 31, 12
    • Counter cache FTW! 1. Select all tweets from user <%= pluralize @user.tweets.length, tweet %> 2. Populate an array of objects 3. Call length on the array <%= pluralize @user.tweets.count, tweet %> 1. Select all tweets from user 2. Do count query for tweets <%= pluralize @user.tweets.size, tweet %> 1. Select all tweets from user belongs_to :user, :counter_cache => trueFriday, August 31, 12
    • Counter cache FTW! 1. Select all tweets from user <%= pluralize @user.tweets.length, tweet %> 2. Populate an array of objects 3. Call length on the array <%= pluralize @user.tweets.count, tweet %> 1. Select all tweets from user 2. Do count query for tweets <%= pluralize @user.tweets.size, tweet %> 1. Select all tweets from user def self.up belongs_to :user, :counter_cache => true add_column :users, :tweets_count, :integer, :default => 0 end def self.down remove_column :users, :tweets_count endFriday, August 31, 12
    • Rails Best PracticesFriday, August 31, 12