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

Conhecendo as Entranhas do Rails

Conhecendo as Entranhas do Rails

Por Rafael França, na RubyConf Brasil 2012.

Plataformatec

August 31, 2012

Transcript

154 slides
  1. Middleware Stack Rack::Cache ActionDispatch::SSL Rack::Sendfile ActionDispatch::Static Rack::Lock Rack::Runtime Rack::MethodOverride ActionDispatch::RequestId

    Rails::Rack::Logger ActionDispatch::ShowExceptions ActionDispatch::DebugExceptions ActionDispatch::RemoteIp ActionDispatch::Reloader ActionDispatch::Callbacks ActionDispatch::Cookies ActionDispatch::Session::CookieStore ActionDispatch::Flash ActionDispatch::ParamsParser Rack::Head Rack::ConditionalGet Rack::ETag ActionDispatch::BestStandardsSupport Rails
  2. Middleware Stack Rack::Cache ActionDispatch::SSL Rack::Sendfile ActionDispatch::Static Rack::Lock Rack::Runtime Rack::MethodOverride ActionDispatch::RequestId

    Rails::Rack::Logger ActionDispatch::ShowExceptions ActionDispatch::DebugExceptions ActionDispatch::RemoteIp ActionDispatch::Reloader ActionDispatch::Callbacks ActionDispatch::Cookies ActionDispatch::Session::CookieStore ActionDispatch::Flash ActionDispatch::ParamsParser Rack::Head Rack::ConditionalGet Rack::ETag ActionDispatch::BestStandardsSupport rails-api
  3. rails-api $ rails new normal_application $ cd normal_application $ rake

    middleware RAILS_ENV=production | wc -l $ rails-api new api_application $ cd api_application $ rake middleware RAILS_ENV=production | wc -l 22 17
  4. Rails::Railtie # railties/lib/rails/all.rb require "rails" %w( active_record action_controller action_mailer rails/test_unit

    sprockets/rails ).each do |framework| begin require "#{framework}/railtie" rescue LoadError end end
  5. module ActiveRecord class Railtie < Rails::Railtie config.active_record = ActiveSupport::OrderedOptions.new config.app_generators.orm

    :active_record, :migration => true, :timestamps => true config.app_middleware.insert_after "::ActionDispatch::Callbacks", "ActiveRecord::QueryCache" # ... config.action_dispatch.rescue_responses.merge!( 'ActiveRecord::RecordNotFound' => :not_found, 'ActiveRecord::StaleObjectError' => :conflict, 'ActiveRecord::RecordInvalid' => :unprocessable_entity, 'ActiveRecord::RecordNotSaved' => :unprocessable_entity ) rake_tasks do # ... end console do |app| # ... end end end Rails::Railtie
  6. module ActiveRecord class Railtie < Rails::Railtie config.active_record = ActiveSupport::OrderedOptions.new config.app_generators.orm

    :active_record, :migration => true, :timestamps => true config.app_middleware.insert_after "::ActionDispatch::Callbacks", "ActiveRecord::QueryCache" # ... end end Rails::Railtie
  7. module ActiveRecord class Railtie < Rails::Railtie config.active_record = ActiveSupport::OrderedOptions.new config.app_generators.orm

    :active_record, :migration => true, :timestamps => true config.app_middleware.insert_after "::ActionDispatch::Callbacks", "ActiveRecord::QueryCache" # ... end end Rails::Railtie
  8. module ActiveRecord class Railtie < Rails::Railtie config.active_record = ActiveSupport::OrderedOptions.new config.app_generators.orm

    :active_record, :migration => true, :timestamps => true config.app_middleware.insert_after "::ActionDispatch::Callbacks", "ActiveRecord::QueryCache" # ... end end Rails::Railtie
  9. module ActiveRecord class Railtie < Rails::Railtie # ... config.action_dispatch.rescue_responses.merge!( 'ActiveRecord::RecordNotFound'

    => :not_found, 'ActiveRecord::StaleObjectError' => :conflict, 'ActiveRecord::RecordInvalid' => :unprocessable_entity, 'ActiveRecord::RecordNotSaved' => :unprocessable_entity ) # ... end end Rails::Railtie
  10. module ActiveRecord class Railtie < Rails::Railtie # ... rake_tasks do

    # ... end console do |app| # ... end end end Rails::Railtie
  11. Rails::Engine module Devise class Engine < ::Rails::Engine config.app_middleware.use Warden::Manager do

    |config| Devise.warden_config = config end config.before_eager_load { |app| app.reload_routes! } initializer "devise.url_helpers" do # ... end initializer "devise.omniauth" do |app| # ... end end end https://github.com/plataformatec/devise
  12. Rails::Engine module Devise class Engine < ::Rails::Engine config.app_middleware.use Warden::Manager do

    |config| Devise.warden_config = config end config.before_eager_load { |app| app.reload_routes! } initializer "devise.url_helpers" do # ... end initializer "devise.omniauth" do |app| # ... end end end https://github.com/plataformatec/devise
  13. Rails::Engine module Devise class Engine < ::Rails::Engine config.app_middleware.use Warden::Manager do

    |config| Devise.warden_config = config end config.before_eager_load { |app| app.reload_routes! } initializer "devise.url_helpers" do # ... end initializer "devise.omniauth" do |app| # ... end end end https://github.com/plataformatec/devise
  14. Rails::Engine module Devise class Engine < ::Rails::Engine config.app_middleware.use Warden::Manager do

    |config| Devise.warden_config = config end config.before_eager_load { |app| app.reload_routes! } initializer "devise.url_helpers" do # ... end initializer "devise.omniauth" do |app| # ... end end end https://github.com/plataformatec/devise
  15. Mountable Engines # ENGINE/config/routes.rb MyBlogEngine::Engine.routes.draw do resources :posts do resources

    :comments end end MyRailsApp::Application.routes.draw do mount MyBlogEngine::Engine => "/blog" end
  16. Isolated Engines module MyBlog class Engine < Rails::Engine end end

    MyBlog::Engine.routes.draw do resources :posts end MyRailsApp::Application.routes.draw do resources :posts mount MyBlog::Engine => "/blog" end posts_path # => PostsController#index
  17. Isolated Engines module MyBlog class Engine < Rails::Engine isolate_namespace MyBlog

    end end MyBlog::Engine.routes.draw do resources :posts end posts_path # => MyBlog::PostsController#index
  18. Rails::Application module MyProject class Application < Rails::Application config.i18n.default_locale = "pt-BR"

    config.encoding = "utf-8" config.filter_parameters += [:password] config.generators do |g| g.orm :mongoid g.test_framework :rspec g.stylesheets false end end end
  19. Rails::Application module MyProject class Application < Rails::Application config.i18n.default_locale = "pt-BR"

    config.encoding = "utf-8" config.filter_parameters += [:password] config.generators do |g| g.orm :mongoid g.test_framework :rspec g.stylesheets false end end end
  20. Rails::Application module MyProject class Application < Rails::Application config.i18n.default_locale = "pt-BR"

    config.encoding = "utf-8" config.filter_parameters += [:password] config.generators do |g| g.orm :mongoid g.test_framework :rspec g.stylesheets false end end end
  21. Rails::Application module MyProject class Application < Rails::Application config.i18n.default_locale = "pt-BR"

    config.encoding = "utf-8" config.filter_parameters += [:password] config.generators do |g| g.orm :mongoid g.test_framework :rspec g.stylesheets false end end end
  22. class UsersController < ActionController::Base def create @user = User.new params[:user]

    if @user.save UserMailer.deliver_welcome_email @user end respond_with @user end end Rails 3
  23. class UsersController < ActionController::Base def create @user = User.new params[:user]

    if @user.save UserMailer.deliver_welcome_email @user end respond_with @user end end Rails 3
  24. class UsersController < ActionController::Base def create @user = User.new params[:user]

    if @user.save UserMailer.deliver_welcome_email @user end respond_with @user end end Rails 4
  25. class ExplainSubscriber # :nodoc: def start(name, id, payload) # unused

    end def finish(name, id, payload) if queries = Thread.current[:queries] unless ignore_payload?(payload) queries << payload.values_at(:sql, :binds) end end end ActiveSupport::Notifications. subscribe("sql.active_record", new) end
  26. class ExplainSubscriber # :nodoc: def start(name, id, payload) # unused

    end def finish(name, id, payload) if queries = Thread.current[:queries] unless ignore_payload?(payload) queries << payload.values_at(:sql, :binds) end end end ActiveSupport::Notifications. subscribe("sql.active_record", new) end
  27. class ExplainSubscriber # :nodoc: def start(name, id, payload) # unused

    end def finish(name, id, payload) if queries = Thread.current[:queries] unless ignore_payload?(payload) queries << payload.values_at(:sql, :binds) end end end ActiveSupport::Notifications. subscribe("sql.active_record", new) end
  28. class ExplainSubscriber # :nodoc: def start(name, id, payload) # unused

    end def finish(name, id, payload) if queries = Thread.current[:queries] unless ignore_payload?(payload) queries << payload.values_at(:sql, :binds) end end end ActiveSupport::Notifications. subscribe("sql.active_record", new) end
  29. def log(sql, name = "SQL", binds = []) @instrumenter.instrument( "sql.active_record",

    :sql => sql, :name => name, :connection_id => object_id, :binds => binds) { yield } # ... end log(sql, name) { @connection.execute(sql) }
  30. def log(sql, name = "SQL", binds = []) @instrumenter.instrument( "sql.active_record",

    :sql => sql, :name => name, :connection_id => object_id, :binds => binds) { yield } # ... end log(sql, name) { @connection.execute(sql) }
  31. def log(sql, name = "SQL", binds = []) @instrumenter.instrument( "sql.active_record",

    :sql => sql, :name => name, :connection_id => object_id, :binds => binds) { yield } # ... end log(sql, name) { @connection.execute(sql) }
  32. def log(sql, name = "SQL", binds = []) @instrumenter.instrument( "sql.active_record",

    :sql => sql, :name => name, :connection_id => object_id, :binds => binds) { yield } # ... end log(sql, name) { @connection.execute(sql) }
  33. def log(sql, name = "SQL", binds = []) @instrumenter.instrument( "sql.active_record",

    :sql => sql, :name => name, :connection_id => object_id, :binds => binds) { yield } # ... end log(sql, name) { @connection.execute(sql) }
  34. def logging_query_plan # ... begin queries = current[:queries] = []

    start = Time.now result = yield if Time.now - start > threshold logger.warn(exec_explain(queries)) end result ensure current[:queries] = nil end end
  35. def logging_query_plan # ... begin queries = current[:queries] = []

    start = Time.now result = yield if Time.now - start > threshold logger.warn(exec_explain(queries)) end result ensure current[:queries] = nil end end
  36. def logging_query_plan # ... begin queries = current[:queries] = []

    start = Time.now result = yield if Time.now - start > threshold logger.warn(exec_explain(queries)) end result ensure current[:queries] = nil end end
  37. def logging_query_plan # ... begin queries = current[:queries] = []

    start = Time.now result = yield if Time.now - start > threshold logger.warn(exec_explain(queries)) end result ensure current[:queries] = nil end end
  38. class ExplainSubscriber # :nodoc: def start(name, id, payload) # unused

    end def finish(name, id, payload) if queries = Thread.current[:queries] unless ignore_payload?(payload) queries << payload.values_at(:sql, :binds) end end end ActiveSupport::Notifications. subscribe("sql.active_record", new) end
  39. class ExplainSubscriber # :nodoc: def start(name, id, payload) # unused

    end def finish(name, id, payload) if queries = Thread.current[:queries] unless ignore_payload?(payload) queries << payload.values_at(:sql, :binds) end end end ActiveSupport::Notifications. subscribe("sql.active_record", new) end
  40. class ExplainSubscriber # :nodoc: def start(name, id, payload) # unused

    end def finish(name, id, payload) if queries = Thread.current[:queries] unless ignore_payload?(payload) queries << payload.values_at(:sql, :binds) end end end ActiveSupport::Notifications. subscribe("sql.active_record", new) end
  41. # config/routes.rb MyApp::Application.routes.draw do resources :messages { resources :comments }

    resources :forwards { resources :comments } resources :uploads { resources :comments } resources :documents { resources :comments } resources :todos { resources :comments } end
  42. # config/routes.rb MyApp::Application.routes.draw do resources :messages { resources :comments }

    resources :forwards { resources :comments } resources :uploads { resources :comments } resources :documents { resources :comments } resources :todos { resources :comments } end
  43. # config/routes.rb MyApp::Application.routes.draw do concerns :commentable do resources :comments end

    resources :messages, :forwards, :uploads, :documents, :todos, :concerns => :commentable end
  44. # config/routes.rb MyApp::Application.routes.draw do concerns :commentable do resources :comments end

    resources :messages, :forwards, :uploads, :documents, :todos, :concerns => :commentable end
  45. # config/routes.rb MyApp::Application.routes.draw do concerns :commentable do resources :comments end

    resources :messages, :forwards, :uploads, :documents, :todos, :concerns => :commentable end
  46. # config/routes.rb MyApp::Application.routes.draw do concerns :commentable do resources :comments end

    resources :messages, :forwards, :uploads, :documents, :todos, :concerns => :commentable end
  47. class PeopleController < ApplicationController def create person = Person.create(params[:person]) respond_with

    person end end class Person < ActiveRecord::Base attr_accessible :name, :age end Rails 3
  48. class PeopleController < ApplicationController def create person = Person.create(params[:person]) respond_with

    person end end class Person < ActiveRecord::Base attr_accessible :name, :age end Rails 3
  49. class PeopleController < ApplicationController def create person = Person.create(params[:person]) respond_with

    person end end class Person < ActiveRecord::Base attr_accessible :name, :age end Rails 3
  50. class PeopleController < ApplicationController def create person = Person.create(params[:person]) respond_with

    person end end class Person < ActiveRecord::Base attr_accessible :name, :age end Rails 3
  51. class Person include ActiveRecord::Model end class PeopleController < ApplicationController def

    create person = Person.create(params[:person]) # BOOM!!!! respond_with person end end Rails 4
  52. class Person include ActiveRecord::Model end class PeopleController < ApplicationController def

    create person = Person.create(params[:person]) # BOOM!!!! respond_with person end end Rails 4
  53. class Person include ActiveRecord::Model end class PeopleController < ApplicationController def

    create person = Person.create(params[:person]) # BOOM!!!! respond_with person end end Rails 4
  54. class Person include ActiveRecord::Model end class PeopleController < ApplicationController def

    create person = Person.create(params[:person]) # BOOM!!!! respond_with person end end Rails 4
  55. class PeopleController < ApplicationController def update person = Person.find(params[:id]) person.update_attributes(person_params)

    respond_with person end private def person_params params.require(:person).permit(:name, :age) end end Rails 4
  56. class PeopleController < ApplicationController def update person = Person.find(params[:id]) person.update_attributes(person_params)

    respond_with person end private def person_params params.require(:person).permit(:name, :age) end end Rails 4
  57. class PeopleController < ApplicationController def update person = Person.find(params[:id]) person.update_attributes(person_params)

    respond_with person end private def person_params params.require(:person).permit(:name, :age) end end Rails 4
  58. class PeopleController < ApplicationController def update person = Person.find(params[:id]) person.update_attributes(person_params)

    respond_with person end private def person_params params.require(:person).permit(:name, :age) end end Rails 4
  59. class PeopleController < ApplicationController def update person = Person.find(params[:id]) person.update_attributes(person_params)

    respond_with person end private def person_params params.require(:person).permit(:name, :age) end end Rails 4
  60. class PostsController < ApplicationController def show @post = Post.find(params[:id]) render

    :json => post_json end private def post_json @post.as_json(:only => [:id, :title, :body], :include => { :comments => { :only => [:id, :body] } } ) end end
  61. class PostsController < ApplicationController def show @post = Post.find(params[:id]) render

    :json => post_json end private def post_json @post.as_json(:only => [:id, :title, :body], :include => { :comments => { :only => [:id, :body] } } ) end end
  62. class PostsController < ApplicationController def show @post = Post.find(params[:id]) render

    :json => post_json end private def post_json @post.as_json(:only => [:id, :title, :body], :include => { :comments => { :only => [:id, :body] } } ) end end
  63. class PostsController < ApplicationController def show @post = Post.find(params[:id]) render

    :json => post_json end private def post_json @post.as_json(:only => [:id, :title, :body], :include => { :comments => { :only => [:id, :body] } } ) end end
  64. class PostsController < ApplicationController def show @post = Post.find(params[:id]) render

    :json => post_json end private def post_json @post.as_json(:only => [:id, :title, :body], :include => { :comments => { :only => [:id, :body] } } ) end end
  65. class PostsController < ApplicationController def show @post = Post.find(params[:id]) render

    :json => post_json end private def post_json @post.as_json(:only => [:id, :title, :body], :include => { :comments => { :only => [:id, :body] } } ) end end
  66. class PostsController < ApplicationController def show @post = Post.find(params[:id]) render

    :json => @post end end # app/serializers/post_serializer.rb class PostSerializer < ActiveModel::Serializer embed :ids, :include => true attributes :id, :title, :body has_many :comments end
  67. class PostsController < ApplicationController def show @post = Post.find(params[:id]) render

    :json => @post end end # app/serializers/post_serializer.rb class PostSerializer < ActiveModel::Serializer embed :ids, :include => true attributes :id, :title, :body has_many :comments end
  68. class PostsController < ApplicationController def show @post = Post.find(params[:id]) render

    :json => @post end end # app/serializers/post_serializer.rb class PostSerializer < ActiveModel::Serializer embed :ids, :include => true attributes :id, :title, :body has_many :comments end
  69. class PostsController < ApplicationController def show @post = Post.find(params[:id]) render

    :json => @post end end # app/serializers/post_serializer.rb class PostSerializer < ActiveModel::Serializer embed :ids, :include => true attributes :id, :title, :body has_many :comments end
  70. class PostsController < ApplicationController def show @post = Post.find(params[:id]) render

    :json => @post end end # app/serializers/post_serializer.rb class PostSerializer < ActiveModel::Serializer embed :ids, :include => true attributes :id, :title, :body has_many :comments end
  71. class PostsController < ApplicationController def show @post = Post.find(params[:id]) render

    :json => @post end end # app/serializers/post_serializer.rb class PostSerializer < ActiveModel::Serializer embed :ids, :include => true attributes :id, :title, :body has_many :comments end
  72. { "post": { "id": 1, "title": "New post", "body": "A

    body!", "comments": [ 1, 2 ] }, "comments": [ { "id": 1, "body": "what a dumb post" }, { "id": 2, "body": "i liked it" }, ] }
  73. { "body": "<p>This is <i>serious</i> monkey business", "id": 1, "title":

    "New post", "comments": [ { "id": 1, "body": "what a dumb post" }, { "id": 2, "body": "i liked it" } ], }

More Decks by Plataformatec

Other Decks in Programming