Skip to content

Instantly share code, notes, and snippets.

@jlucasps
Last active December 25, 2015 20:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jlucasps/7037824 to your computer and use it in GitHub Desktop.
Save jlucasps/7037824 to your computer and use it in GitHub Desktop.
Rails roadmap
rails-0.10.0: Routing, Web Services, Components, Oracle
active support:
class e module attribute accessors:
Extends the class object with class and instance accessors for class attributes
Extends the module object with module and instance accessors for class attributes
inflectors:
The Inflector transforms words from singular to plural, class names to table names, modularized class names
to ones without, and class names to foreign key.
breakpoints:
The Breakpoint library provides the convenience of being able to inspect and modify state, diagnose
bugs all via IRB by simply setting breakpoints in your applications by the call of a method.
core_ext:
Adiciona comportamentos convenientes a diversas classes Ruby
time:
calculations:
Mudar campos específicos em uma data. Por exemplo, mudar do ano 2005 para 2006
assert_equal Time.local(2006,2,22,15,15,10), Time.local(2005,2,22,15,15,10).change(:year => 2006)
Retornar uma nova data sendo um número de segundos antes ou depois de uma certa data. Por ex,
assert_equal Time.local(2005,2,22,10,10,9), Time.local(2005,2,22,10,10,10).ago(1)
assert_equal Time.local(2005,2,20,10,10,10), Time.local(2005,2,22,10,10,10).ago(86400*2)
Retornar uma nova data sendo o início do dia, semana ou mês
assert_equal Time.local(2005,1,31), Time.local(2005,2,4,10,10,10).beginning_of_week
assert_equal Time.local(2005,2,4,0,0,0), Time.local(2005,2,4,10,10,10).beginning_of_day
conversions:
Getting times in different convenient string representations and other objects
assert_equal "February 21, 2005 17:44", Time.local(2005, 2, 21, 17, 44, 30).to_s(:long)
assert_equal Date.new(2005, 2, 21), Time.local(2005, 2, 21, 17, 44, 30).to_date
string:
inflections:
Makes it possible to do "posts".singularize that returns "post" and "MegaCoolClass".underscore that returns "mega_cool_class".
"ApplicationController" => "application_controller"
"UsersSection::CommissionDepartment" => "users_section/commission_department"
"Person" => "person_id"
"NodeChild" => "node_children"
numeric:
byte:
Enables the use of byte calculations and declarations, like 45.bytes + 2.6.megabytes
1024.kilobytes => 1.megabyte
1.kilobyte ** 4 => 1.terabyte
time:
Enables the use of time calculations and declarations, like 45.minutes + 2.hours + 4.years
1.minute => 60
1.hour + 15.minutes => 4500
2.days + 4.hours + 30.minutes => 189000
hash:
stringify_keys, symbolize_keys e indifferent_access
strings = { 'a' => 1, 'b' => 2 }
symbols = { :a => 1, :b => 2 }
mixed = { :a => 1, 'b' => 2 }
date:
conversions:
Getting dates in different convenient string representations and other objects
assert_equal "February 21, 2005", Date.new(2005, 2, 21).to_s(:long)
assert_equal Time.local(2005, 2, 21), Date.new(2005, 2, 21).to_time
active record:
connections:
db2, mysql, oracle, postgresql, sqlite, sqlite3, sqlserver
mapping:
class Product < ActiveRecord::Base; end
is automatically mapped to the table named "products",
associations:
class Firm < ActiveRecord::Base
has_many :clients
has_one :account
belongs_to :conglomorate
has_and_belongs_to_many :investors
end
natural assignments:
apple.account = citibank
assert_equal apple.id, citibank.firm_id
validations:
Validation rules that can differ for new or existing objects
class Account < ActiveRecord::Base
validates_presence_of :subdomain, :name, :email_address, :password
validates_uniqueness_of :subdomain
validates_acceptance_of :terms_of_service, :on => :create
validates_confirmation_of :password, :email_address, :on => :create
end
callbacks:
Callbacks as methods or queues on the entire lifecycle (instantiation, saving, destroying, validating, etc).
:after_find, :after_initialize, :before_validation, :before_validation_on_update, :after_validation, :after_validation_on_update, :before_save, :before_update, :after_update, :after_save, :before_destroy, :after_destroy
finds and dynamic methods:
Firm.find(1, 2)
Company.find_first "name = 'Next Angle'"
Firm.find_by_sql("SELECT * FROM companies WHERE id = 1").first
Topic.find(1, :conditions => "approved = 1")
Topic.find_by_title("The First Topic")
Topic.find_by_title_and_author_name("The First Topic", "David")
Topic.find_all_by_content("Have a nice day")
next_angle.clients.find(2)
next_angle.clients.empty?
next_angle.clients.size
action pack:
Action Pack splits the response to a web request into a controller part (performing the logic) and a view
part (rendering a template). This two-step approach is known as an action, which will normally create, read, update,
or delete (CRUD for short) some sort of model part (often backed by a database) before choosing either to render a
template or redirecting to another action
action controller:
Action Controllers are then responsible for handling all the actions relating to a certain part of an application.
This grouping usually consists of actions for lists and for CRUDs revolving around a single (or a few) model objects
Actions grouped in controller as methods instead of separate command objects:
BlogController < ActionController::Base
def display
@customer = find_customer
end
private
def find_customer() Customer.find(@params["id"]) end
end
Filters for pre and post processing of the response:
lass WeblogController < ActionController::Base
before_filter :authenticate, :cache, :audit
after_filter { |c| c.response.body = GZip::compress(c.response.body) }
Layout sharing for template reuse:
class WeblogController < ActionController::Base
layout "weblog_layout"
def hello_world
end
end
Scaffolding for Action Record model objects:
require 'account' # must be an Active Record class
class AccountController < ActionController::Base
scaffold :account
end
# templates: list, show, destroy, new, create, edit, update
Advanced redirection that makes pretty urls easy:
RewriteRule ^/library/books/([A-Z]+)([0-9]+)/([-_a-zA-Z0-9]+)$ \
/books_controller.cgi?action=$3&type=$1&code=$2 [QSA] [L]
Accessing /library/books/ISBN/0743536703/show calls BooksController#show
action view:
Action View templates are written using embedded Ruby in tags mingled in with the HTML. To avoid cluttering the
templates with code, a bunch of helper classes provide common behavior for forms, dates, and strings.
Embedded Ruby for templates:
<% for post in @posts %>
Title: <%= post.title %>
<% end %>
Helpers for forms, dates, action links, and text:
<%= text_field "post", "title", "size" => 30 %>
<%= html_date_select(Date.today) %>
<%= link_to "New post", :controller => "post", :action => "new" %>
<%= truncate(post.title, 25) %>
Form building for Active Record model objects:
<%= form "post" %>
This form generates a @params["post"] array that can be used directly in a save action
Rendering shared partials:
<%= render_partial "advertisement/ad", ad %>
action mailer:
Action Mailer is framework for designing email-service layers.
The framework works by setting up all the email details, except the body:
def signed_up(recipient)
@recipients = recipient
@subject = "[Signed up] Welcome #{recipient}"
@from = "system@loudthinking.com"
@sent_on = Time.local(2004, 12, 12)
@body["recipient"] = recipient
end
The body of the email is created by using an Action View template (regular ERb)
ApplicationMailer.deliver_signed_up("david@loudthinking.com") # sends the email
rails-0.11.0: Ajax, Pagination, Non-vhost, Incoming mail
active support:
string to date and time:
assert_equal Time.utc(2005, 2, 27, 23, 50), "2005-02-27 23:50".to_time
assert_equal Date.new(2005, 2, 27), "2005-02-27".to_date
active record:
Oracle native to OCI Oracle
action pack:
ajax
action mailer:
incoming mails
rails-0.12.0: Eager associations, new Base.find API, assertions revisited, more Ajax!
# Turning N+1 queries into 1
for post in Post.find(:all, :include => [ :author, :comments ])
puts "Post: " + post.title
puts "Written by: " + post.author.name
puts "Last comment on: " + post.comments.first.created_on
end
Person.find(1, :conditions =>"administrator = 1", :order =>"created_on DESC")
Person.find(1, 5, 6, :conditions =>"administrator = 1", :order =>"created_on DESC")
Person.find(:first, :order =>"created_on DESC", :offset => 5)
Person.find(:all, :conditions => [ "category IN (?)", categories], :limit => 50)
Person.find(:all, :offset => 10, :limit => 10)
rails-0.13:
Using script.aculo.us to visual effects, drag’n’drop, sortable lists, auto-completing text fields
remote link:
link_to_remote(
"test",
:url => { :action =>"faulty" },
:update => { :success =>"good", :failure =>"bad" },
403 =>"alert('Forbidden- got ya!')",
404 =>"alert('Nothing there...?')",
:failure =>"alert('Unkown error ' + request.status)"
)
Migrations for PostgreSQL and MySQL:
With migrations, you can describe the transformations in self-contained classes that can be checked
into version control systems and executed against another database that might be one, two, or five versions behind.
Rendering: One method to bind them all
Routes: Giving them a name and calling them by it
map.home '', :controller => 'main', :action => 'start'
edirect_to :controller => 'main', :action => 'start' ... is now redirect_to :home_url
Mail attachments
Conditional validations:
validates_numericality_of :income, :if => :employed?
validates_presence_of :username, :if => Proc.new { |user| user.signup_step > 1 }
rails-1.0 :
script/plugin:
Helps you install, manage, and discover new plugins
Active Record:
find_or_create_by_X, association collection extensions, migrations for all databases
rails-1.1.0
gzip compression for JavaScript, CSS, and HTML to default lighttpd.conf
Avoid passing escapeHTML non-string in Rails' info controller
RJS: JavaScript written in Ruby
Polymorphic associations:
class Address < ActiveRecord::Base
belongs_to :addressable, :polymorphic => true
end
class Person < ActiveRecord::Base
has_one :address, :as => :addressable
end
class Company < ActiveRecord::Base
has_one :address, :as => :addressable
end
Calculations:
sum, average, count, max
Eager loading:
# Single database query:
companies = Company.find(:all, :include => { :groups => { :members=> { :favorites } } })
# Just 1 database query for all of this:
authors = Author.find(:all, :include => [ { :posts => :comments }, :categorizations ])
authors[0].posts[0].comments[0].body # => "Rock on Rails!"
authors[0].categorizations[0].name # => "Less software"
respond_to: Launch your application with both Ajax, non-Ajax, and API access through the same actions
def create
@post = Post.create(params[:post])
respond_to do |type|
type.js { render } # renders create.rjs
type.html { redirect_to :action => "index" }
type.xml do
headers["Location"] = post_url(:id => @post)
render(:nothing, :status => "201 Created")
end
end
end
Integration tests:
They allow you to faithfully simulate users accessing multiple controllers and even gives
you the power to simulate multiple concurrent users.
rails-1.2
REST, formats and respond_to:
class WeblogController < ActionController::Base
def index
@posts = Post.find :all
respond_to do |format|
format.html
format.xml { render :xml => @posts.to_xml }
format.rss { render :action => “feed.rxml” }
end
end
end
GET /weblog # returns HTML from browser Accept header
GET /weblog.xml # returns the XML
GET /weblog.rss # returns the RSS
Auto-loading:
Module loading, which means that a reference for Accounting::Subscription will look
for app/models/accounting/subscription.rb.
Referencing Subscription will not look for subscription.rb in any subdir of app/models.
Only app/models/subscription.rb will be tried.
rails-1.2.2:
single resource:
map.resource :account
rails-2 preview:
Action Pack: Resources:
namespaces e collection resources
Action Pack: Multiview:
So show.rhtml now becomes show.html.erb, which is the template that’ll be rendered by default
for a show action that has declared format.html in its respond_to.
Action Pack: Record identification:
# person is a Person object, which by convention will
# be mapped to person_url for lookup
redirect_to(person)
link_to(person.name, person)
form_for(person)
Action Pack: Security:
Most importantly, we now ship we a built-in mechanism for dealing with CRSF attacks.
By including a special token in all forms and Ajax requests, you can guard from having requests made
from outside of your application.
ActionWebService out, ActiveResource in:
It’ll probably come as no surprise that Rails has picked a side in the SOAP vs REST debate.
Unless you absolutely have to use SOAP for integration purposes, we strongly discourage you from doing so.
Action Pack: Exception handling:
class PostsController < ApplicationController
rescue_from User::NotAuthorized, :with => :deny_access
protected
def deny_access
...
end
end
rails-2.1: Time zones, dirty, caching, gem dependencies, caching, etc
change tracking methods:
p.changed?
p.changes
p.name_changed?
gem dependencies:
gem verions at config/environments/test.rb
named scopes:
class Product < ActiveRecord::Base
belongs_to :category
named_scope :cheap, :conditions => { :price => 0..5 }
named_scope :recent, lambda { |*args| {:conditions => ["released_at > ?", (args.first || 2.weeks.ago)]} }
named_scope :visible, :include => :category, :conditions => { 'categories.hidden' => false }
end
rails-2.2
i18n internacionalization
Ruby 1.9 and JRuby compatible
rails-2.3:
nested attributes:
class Book < ActiveRecord::Base
has_one :author
has_many :pages
accepts_nested_attributes_for :author, :pages
end
default scopes
adopted Rack
Multiple Conditions for Callbacks:
before_save :update_credit_rating, :if => :active, :unless => [:admin, :cash_only]
Find with having:
developers = Developer.find(:all, :group => "salary", :having => "sum(salary) > 10000", :select => "salary")
Unified Rendering:
render '/tmp/random_file.erb'
render 'other_controller/action'
render 'show'
render :show
Smart Rendering of Partials:
# Equivalent of render :partial => 'articles/_article',
# :object => @article
render @article
rails-2.3.6:
flash keys to alert and notice
I18n to internacionalize label_helper
rails-3:
New ActiveRecord query engine:
users = User.where(:name => "david").limit(20)
users.order(:name).each { |user| puts user.name }
Manage dependencies with Bundler:
All Rails 3 applications are born with a Gemfile
Active Model: Validations, callbacks, etc for all models:
Agnosticism with jQuery, rSpec, and Data Mapper:
DataMapper -> Active Record
Query -> Prototype
Spec -> test/unit
rails-3.1:
AssetPipeline:
Sprockets, SCSS, CoffeeScript
JQuery default
Reversible migrations
asset paths when pipeline is on
rails-3.2:
Faster dev mode & routing:
Only reload classes from files you’ve actually changed. The difference is dramatic on a larger application.
Extract your vendor/plugins to their own gems and bundle them in your Gemfile.
Explain queries
rails-3.2.X:
critical security fixies:
CVE-2012-5664, CVE-2013-0155, CVE-2013-0156, CVE-2013-0333
rails-4:
Turbolinks
Live streaming
Scopes as callable objects
Mass assignment protection from models to Controllers
ActiveModel::Model:
update its attributes through a form, but not persist it to the database
we can create attr_accessors for any method we want
add validations just like we would with ActiveRecord
Remove resources duplication using concerns:
concern :commentable do
resources :comments
end
resources :articles, concerns: :commentable
resources :photos, concerns: :commentable
Deprecating match and using get, post, patch
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment