SlideShare a Scribd company logo
Wider Than Rails:
Lightweight Ruby
    Solutions
 Alexey Nayden, EvilMartians.com
          RubyC 2011
Lightweight != Fast

Lightweight ≈ Simple
Less code
         =
Easier to maintain
         =
        (often)


      Faster
Motives to travel light

•   Production performance

•   Complexity overhead

•   Learning curve

•   More flexibility

•   Self-improvement
Do you always need all
$ ls
      of that?
app/
config/
db/
doc/
Gemfile
lib/
log
public/
Rakefile
README
script/
spec/
test/
tmp/
vendor/
www/
Gemfile.lock
.rspec
config.ru
Do you always need all
$ ls
      of that?
app/
config/
db/
doc/
Gemfile
lib/
log
public/
Rakefile
README
script/
spec/
test/
tmp/
vendor/
www/
Gemfile.lock
.rspec
config.ru
Lightweight plan

• Replace components of your framework
• Inject lightweight tools
• Migrate to a different platform
• Don't forget to be consistent
ActiveRecord? Sequel!

•   http://sequel.rubyforge.org

•   Sequel is a gem providing both raw SQL and neat
    ORM interfaces

•   18 DBMS support out of the box

•   25—50% faster than ActiveRecord

•   100% ActiveModel compliant
Sequel ORM
class UsersController < ApplicationController
  before_filter :find_user, :except => [:create]
  def create
   @user = User.new(params[:user])
  end
  protected
   def find_user
     @user = User[params[:id]]
   end
end
Sequel Model
class User < Sequel::Model
  one_to_many :comments
  subset(:active){comments_count > 20}

 plugin :validation_helpers
 def validate
   super
   validates_presence [:email, :name]
   validates_unique :email
   validates_integer :age if new?
 end

  def before_create
    self.created_at ||= Time.now # however there's a plugin
    super                        # for timestamping
  end
end
Raw SQL
DB.fetch("SELECT * FROM albums WHERE name LIKE :pattern", :pattern=>'A%') do |row|
  puts row[:name]
end

DB.run "CREATE TABLE albums (id integer primary key, name varchar(255))"

db(:legacy).fetch("
      SELECT
      (SELECT count(*) FROM activities WHERE
            ACTION = 'logged_in'
            AND
            DATE(created_at) BETWEEN DATE(:start) AND DATE(:end)
       ) AS login_count,
      (SELECT count(*) FROM users WHERE
        (DATE(created_at) BETWEEN DATE(:start) AND DATE(:end))
        AND
        (activated_at IS NOT NULL)
      ) AS user_count",
 :start => start_date, :end => end_date)
Benchmarks
Clean frontend with
         Zepto.js
•   http://zeptojs.com

•   JS framework for with a jQ-compatible syntax
    and API

•   Perfect for rich mobile (esp. iOS) web-apps, but
    works in any modern browser except IE

•   7.5 Kb at the moment (vs. 31 Kb jQ)

•   Officially — beta, but used at mobile version of
    Groupon production-ready
Good old $
$('p>span').html('Hello, RubyC').css('color:red');




      Well-known syntax
$('p').bind('click', function(){
  $('span', this).css('color:red');
});



Touch UI? No problem!
$('some   selector').tap(function(){ ... });
$('some   selector').doubleTap(function(){ ... });
$('some   selector').swipeRight(function(){ ... });
$('some   selector').pinch(function(){ ... });
Xtra Xtra Small: Rack

• Rack is a specification of a minimal Ruby
  API that models HTTP
• One might say Rack is a CGI in a Ruby
  world
• Only connects a webserver with your
  «app» (actually it can be just a lambda!)
Rack
•   You need to have an object with a method
    call(env)

•   It should return an array with 3 elements
    [status_code, headers, body]

•   So now you can connect it with any webserver
    that supports Rack
    require ‘thin’
    Rack::Handler::Thin.run(app, :Port => 4000)

•   Lightweight webapp completed
Rack App Example
class ServerLoad
  def call(env)
    [200, {"Content-Type" => "text/plain"}, ["uptime | cut -f 11 -d ' '"]]
  end
end
Metal. Rack on Rails
•   ActionController::Metal is a way to get a valid Rack
    app from a controller

•   A bit more comfortable dealing with Rack inside
    Rails

•   You still can include any parts of ActionController
    stack inside your metal controller

•   Great for API`s
Metallic API
class ApiController < ActionController::Metal
  include AbstractController::Callbacks
  include ActionController::Helpers
  include Devise::Controllers::Helpers
  before_filter :require_current_user

  def history
    content_type = "application/json"
    recipient = User.find(params[:user_id])
    messages = Message.between(current_user, recipient)

    if params[:start_date]
      response_body = messages.after(params[:start_date]).to_json
    else
      response_body = messages.recent.to_json
    end

  end
end
Sinatra
•   Sinatra should be considered as a compact
    framework (however they prefer calling it DSL)
    replacing ActionController and router

•   You still can include ActiveRecord, ActiveSupport
    or on the other side — include Sinatra app inside
    Rails app

•   But you can also go light with Sequel / DataMapper
    and plaintext / XML / JSON output
Sinatra
require 'rubygems'
require 'sinatra'

get '/' do
  haml :index
end

post '/signup' do
  Spam.deliver(params[:email])
end

mime :json, 'application/json'
get '/events/recent.json' do
  content_type :json
  Event.recent.to_json
end
Padrino. DSL evolves to
     a framework
• http://www.padrinorb.com/
• Based on a Sinatra and brings LIKE-A-BOSS
  comfort to a Sinatra development process
• Fully supports 6 ORMs, 5 JS libs, 2
  rendering engines, 6 test frameworks, 2
  stylesheet engines and 2 mocking libs out
  of the box
• Still remains quick and simple
Padrino blog
$ padrino g project sample_blog -t shoulda -e haml 
    -c sass -s jquery -d activerecord -b
  class SampleBlog < Padrino::Application
    register Padrino::Helpers
    register Padrino::Mailer
    register SassInitializer

    get "/" do
      "Hello World!"
    end

    get :about, :map => '/about_us' do
      render :haml, "%p This is a sample blog"
    end

  end
Posts controller
SampleBlog.controllers :posts do
  get :index, :provides => [:html, :rss, :atom] do
    @posts = Post.all(:order => 'created_at desc')
    render 'posts/index'
  end

  get :show, :with => :id do
    @post = Post.find_by_id(params[:id])
    render 'posts/show'
  end
end
A little bit of useless
     benchmarking
• We take almost plain «Hello World»
  application and run
  ab ‐c 10 ‐n 1000
• rack 1200 rps
• sinatra 600 rps
• padrino 570 rps
• rails 140 rps
Tools
They don't need to be huge and slow
Pow
• http://pow.cx/
• A 37signals Rack-based webserver for
  developer needs
• One-line installer, unobtrusive, fast and only
  serves web-apps, nothing else
• cd ~/.pow
  ln ‐s /path/to/app
rbenv

• https://github.com/sstephenson/rbenv
• Small, quick, doesn't modify shell
  commands, UNIX-way
• rbenv global 1.9.2‐p290
  cd /path/to/app
  rbenv local jruby‐1.6.4
One more thing...
Ruby is not a silver
            bullet
You should always consider different platforms and
   languages: Erlang, Scala, .NET and even C++
Ruby is not a silver
            bullet
You should always consider different platforms and
   languages: Erlang, Scala, .NET and even C++

 Don't miss Timothy Tsvetkov's speech
              tomorrow
Questions?
alexey.nayden@evilmartians.com

More Related Content

PDF
Mini Rails Framework
PDF
Ansible 202 - sysarmy
PDF
Fast Web Applications Development with Ruby on Rails on Oracle
PPTX
Javascript asynchronous
PDF
Beautiful code instead of callback hell using ES6 Generators, Koa, Bluebird (...
PDF
Extending Oracle E-Business Suite with Ruby on Rails
PDF
Development of Ansible modules
PDF
CouchDB for Web Applications - Erlang Factory London 2009
Mini Rails Framework
Ansible 202 - sysarmy
Fast Web Applications Development with Ruby on Rails on Oracle
Javascript asynchronous
Beautiful code instead of callback hell using ES6 Generators, Koa, Bluebird (...
Extending Oracle E-Business Suite with Ruby on Rails
Development of Ansible modules
CouchDB for Web Applications - Erlang Factory London 2009

What's hot (20)

PPTX
Ansible module development 101
KEY
Rails and Legacy Databases - RailsConf 2009
PDF
Matthew Eernisse, NodeJs, .toster {webdev}
PDF
ECMAScript 6
PDF
Rhebok, High Performance Rack Handler / Rubykaigi 2015
PDF
IVS CTO Night And Day 2018 Winter - [re:Cap] Serverless & Mobile
PPTX
ECMAScript 6 and the Node Driver
PDF
Celery introduction
PDF
Ansible 202
PDF
Ruby HTTP clients comparison
PDF
What's New in ES6 for Web Devs
PDF
Phoenix for Rails Devs
PDF
Practical Testing of Ruby Core
PDF
Using Node.js to Build Great Streaming Services - HTML5 Dev Conf
PDF
Kotlin 1.2: Sharing code between platforms
PDF
Introduction to asynchronous DB access using Node.js and MongoDB
KEY
Psgi Plack Sfpm
PPTX
How to create a libcloud driver from scratch
PPTX
How to create a libcloud driver from scratch
KEY
Building a real life application in node js
Ansible module development 101
Rails and Legacy Databases - RailsConf 2009
Matthew Eernisse, NodeJs, .toster {webdev}
ECMAScript 6
Rhebok, High Performance Rack Handler / Rubykaigi 2015
IVS CTO Night And Day 2018 Winter - [re:Cap] Serverless & Mobile
ECMAScript 6 and the Node Driver
Celery introduction
Ansible 202
Ruby HTTP clients comparison
What's New in ES6 for Web Devs
Phoenix for Rails Devs
Practical Testing of Ruby Core
Using Node.js to Build Great Streaming Services - HTML5 Dev Conf
Kotlin 1.2: Sharing code between platforms
Introduction to asynchronous DB access using Node.js and MongoDB
Psgi Plack Sfpm
How to create a libcloud driver from scratch
How to create a libcloud driver from scratch
Building a real life application in node js
Ad

Viewers also liked (8)

PDF
Wider than rails
PDF
Технические аспекты знакоства с девушкой в Интернете
KEY
Haml/Sassを使って履歴書を書くためのn個の方法
PDF
Хэши в ruby
KEY
Sequel — механизм доступа к БД, написанный на Ruby
PDF
«Работа с базами данных с использованием Sequel»
PPTX
развертывание среды Rails (антон веснин, Locum Ru)
ODP
Top10 доводов против языка Ruby
Wider than rails
Технические аспекты знакоства с девушкой в Интернете
Haml/Sassを使って履歴書を書くためのn個の方法
Хэши в ruby
Sequel — механизм доступа к БД, написанный на Ruby
«Работа с базами данных с использованием Sequel»
развертывание среды Rails (антон веснин, Locum Ru)
Top10 доводов против языка Ruby
Ad

Similar to Wider than rails (20)

PDF
Rails 3 : Cool New Things
PDF
RubyEnRails2007 - Dr Nic Williams - Keynote
KEY
Why ruby and rails
PPTX
Exploring Ruby on Rails and PostgreSQL
PDF
Strangers In The Night: Ruby, Rack y Sinatra - Herramientas potentes para con...
PDF
Ruby off Rails (english)
PDF
Rails - getting started
PDF
Web Development using Ruby on Rails
PDF
Riding on rails3 with full stack of gems
PDF
Using Sinatra to Build REST APIs in Ruby
PDF
Sinatra Introduction
DOC
Rails interview questions
PDF
Ruby on-rails-101-presentation-slides-for-a-five-day-introductory-course-1194...
KEY
Rapid development with Rails
PDF
JRuby, Ruby, Rails and You on the Cloud
PDF
Sinatra Rack And Middleware
PDF
Ruby On Rails Basics
PDF
Sinatra and JSONQuery Web Service
PDF
TorqueBox at DC:JBUG - November 2011
PDF
Avik_RailsTutorial
Rails 3 : Cool New Things
RubyEnRails2007 - Dr Nic Williams - Keynote
Why ruby and rails
Exploring Ruby on Rails and PostgreSQL
Strangers In The Night: Ruby, Rack y Sinatra - Herramientas potentes para con...
Ruby off Rails (english)
Rails - getting started
Web Development using Ruby on Rails
Riding on rails3 with full stack of gems
Using Sinatra to Build REST APIs in Ruby
Sinatra Introduction
Rails interview questions
Ruby on-rails-101-presentation-slides-for-a-five-day-introductory-course-1194...
Rapid development with Rails
JRuby, Ruby, Rails and You on the Cloud
Sinatra Rack And Middleware
Ruby On Rails Basics
Sinatra and JSONQuery Web Service
TorqueBox at DC:JBUG - November 2011
Avik_RailsTutorial

Recently uploaded (20)

PDF
Empathic Computing: Creating Shared Understanding
PPTX
TechTalks-8-2019-Service-Management-ITIL-Refresh-ITIL-4-Framework-Supports-Ou...
PDF
Agricultural_Statistics_at_a_Glance_2022_0.pdf
PDF
Blue Purple Modern Animated Computer Science Presentation.pdf.pdf
PDF
Profit Center Accounting in SAP S/4HANA, S4F28 Col11
PDF
Univ-Connecticut-ChatGPT-Presentaion.pdf
PPTX
Spectroscopy.pptx food analysis technology
PDF
Diabetes mellitus diagnosis method based random forest with bat algorithm
PDF
Accuracy of neural networks in brain wave diagnosis of schizophrenia
PDF
Per capita expenditure prediction using model stacking based on satellite ima...
PDF
Heart disease approach using modified random forest and particle swarm optimi...
PDF
Spectral efficient network and resource selection model in 5G networks
PPTX
Machine Learning_overview_presentation.pptx
PDF
Reach Out and Touch Someone: Haptics and Empathic Computing
PPTX
1. Introduction to Computer Programming.pptx
PPTX
Programs and apps: productivity, graphics, security and other tools
PDF
Architecting across the Boundaries of two Complex Domains - Healthcare & Tech...
PPTX
cloud_computing_Infrastucture_as_cloud_p
PDF
gpt5_lecture_notes_comprehensive_20250812015547.pdf
PPTX
OMC Textile Division Presentation 2021.pptx
Empathic Computing: Creating Shared Understanding
TechTalks-8-2019-Service-Management-ITIL-Refresh-ITIL-4-Framework-Supports-Ou...
Agricultural_Statistics_at_a_Glance_2022_0.pdf
Blue Purple Modern Animated Computer Science Presentation.pdf.pdf
Profit Center Accounting in SAP S/4HANA, S4F28 Col11
Univ-Connecticut-ChatGPT-Presentaion.pdf
Spectroscopy.pptx food analysis technology
Diabetes mellitus diagnosis method based random forest with bat algorithm
Accuracy of neural networks in brain wave diagnosis of schizophrenia
Per capita expenditure prediction using model stacking based on satellite ima...
Heart disease approach using modified random forest and particle swarm optimi...
Spectral efficient network and resource selection model in 5G networks
Machine Learning_overview_presentation.pptx
Reach Out and Touch Someone: Haptics and Empathic Computing
1. Introduction to Computer Programming.pptx
Programs and apps: productivity, graphics, security and other tools
Architecting across the Boundaries of two Complex Domains - Healthcare & Tech...
cloud_computing_Infrastucture_as_cloud_p
gpt5_lecture_notes_comprehensive_20250812015547.pdf
OMC Textile Division Presentation 2021.pptx

Wider than rails

  • 1. Wider Than Rails: Lightweight Ruby Solutions Alexey Nayden, EvilMartians.com RubyC 2011
  • 3. Less code = Easier to maintain = (often) Faster
  • 4. Motives to travel light • Production performance • Complexity overhead • Learning curve • More flexibility • Self-improvement
  • 5. Do you always need all $ ls of that? app/ config/ db/ doc/ Gemfile lib/ log public/ Rakefile README script/ spec/ test/ tmp/ vendor/ www/ Gemfile.lock .rspec config.ru
  • 6. Do you always need all $ ls of that? app/ config/ db/ doc/ Gemfile lib/ log public/ Rakefile README script/ spec/ test/ tmp/ vendor/ www/ Gemfile.lock .rspec config.ru
  • 7. Lightweight plan • Replace components of your framework • Inject lightweight tools • Migrate to a different platform • Don't forget to be consistent
  • 8. ActiveRecord? Sequel! • http://sequel.rubyforge.org • Sequel is a gem providing both raw SQL and neat ORM interfaces • 18 DBMS support out of the box • 25—50% faster than ActiveRecord • 100% ActiveModel compliant
  • 9. Sequel ORM class UsersController < ApplicationController before_filter :find_user, :except => [:create] def create @user = User.new(params[:user]) end protected def find_user @user = User[params[:id]] end end
  • 10. Sequel Model class User < Sequel::Model one_to_many :comments subset(:active){comments_count > 20} plugin :validation_helpers def validate super validates_presence [:email, :name] validates_unique :email validates_integer :age if new? end def before_create self.created_at ||= Time.now # however there's a plugin super # for timestamping end end
  • 11. Raw SQL DB.fetch("SELECT * FROM albums WHERE name LIKE :pattern", :pattern=>'A%') do |row| puts row[:name] end DB.run "CREATE TABLE albums (id integer primary key, name varchar(255))" db(:legacy).fetch(" SELECT (SELECT count(*) FROM activities WHERE ACTION = 'logged_in' AND DATE(created_at) BETWEEN DATE(:start) AND DATE(:end) ) AS login_count, (SELECT count(*) FROM users WHERE (DATE(created_at) BETWEEN DATE(:start) AND DATE(:end)) AND (activated_at IS NOT NULL) ) AS user_count", :start => start_date, :end => end_date)
  • 13. Clean frontend with Zepto.js • http://zeptojs.com • JS framework for with a jQ-compatible syntax and API • Perfect for rich mobile (esp. iOS) web-apps, but works in any modern browser except IE • 7.5 Kb at the moment (vs. 31 Kb jQ) • Officially — beta, but used at mobile version of Groupon production-ready
  • 14. Good old $ $('p>span').html('Hello, RubyC').css('color:red'); Well-known syntax $('p').bind('click', function(){ $('span', this).css('color:red'); }); Touch UI? No problem! $('some selector').tap(function(){ ... }); $('some selector').doubleTap(function(){ ... }); $('some selector').swipeRight(function(){ ... }); $('some selector').pinch(function(){ ... });
  • 15. Xtra Xtra Small: Rack • Rack is a specification of a minimal Ruby API that models HTTP • One might say Rack is a CGI in a Ruby world • Only connects a webserver with your «app» (actually it can be just a lambda!)
  • 16. Rack • You need to have an object with a method call(env) • It should return an array with 3 elements [status_code, headers, body] • So now you can connect it with any webserver that supports Rack require ‘thin’ Rack::Handler::Thin.run(app, :Port => 4000) • Lightweight webapp completed
  • 17. Rack App Example class ServerLoad def call(env) [200, {"Content-Type" => "text/plain"}, ["uptime | cut -f 11 -d ' '"]] end end
  • 18. Metal. Rack on Rails • ActionController::Metal is a way to get a valid Rack app from a controller • A bit more comfortable dealing with Rack inside Rails • You still can include any parts of ActionController stack inside your metal controller • Great for API`s
  • 19. Metallic API class ApiController < ActionController::Metal include AbstractController::Callbacks include ActionController::Helpers include Devise::Controllers::Helpers before_filter :require_current_user def history content_type = "application/json" recipient = User.find(params[:user_id]) messages = Message.between(current_user, recipient) if params[:start_date] response_body = messages.after(params[:start_date]).to_json else response_body = messages.recent.to_json end end end
  • 20. Sinatra • Sinatra should be considered as a compact framework (however they prefer calling it DSL) replacing ActionController and router • You still can include ActiveRecord, ActiveSupport or on the other side — include Sinatra app inside Rails app • But you can also go light with Sequel / DataMapper and plaintext / XML / JSON output
  • 21. Sinatra require 'rubygems' require 'sinatra' get '/' do haml :index end post '/signup' do Spam.deliver(params[:email]) end mime :json, 'application/json' get '/events/recent.json' do content_type :json Event.recent.to_json end
  • 22. Padrino. DSL evolves to a framework • http://www.padrinorb.com/ • Based on a Sinatra and brings LIKE-A-BOSS comfort to a Sinatra development process • Fully supports 6 ORMs, 5 JS libs, 2 rendering engines, 6 test frameworks, 2 stylesheet engines and 2 mocking libs out of the box • Still remains quick and simple
  • 23. Padrino blog $ padrino g project sample_blog -t shoulda -e haml -c sass -s jquery -d activerecord -b class SampleBlog < Padrino::Application register Padrino::Helpers register Padrino::Mailer register SassInitializer get "/" do "Hello World!" end get :about, :map => '/about_us' do render :haml, "%p This is a sample blog" end end
  • 24. Posts controller SampleBlog.controllers :posts do get :index, :provides => [:html, :rss, :atom] do @posts = Post.all(:order => 'created_at desc') render 'posts/index' end get :show, :with => :id do @post = Post.find_by_id(params[:id]) render 'posts/show' end end
  • 25. A little bit of useless benchmarking • We take almost plain «Hello World» application and run ab ‐c 10 ‐n 1000 • rack 1200 rps • sinatra 600 rps • padrino 570 rps • rails 140 rps
  • 26. Tools They don't need to be huge and slow
  • 27. Pow • http://pow.cx/ • A 37signals Rack-based webserver for developer needs • One-line installer, unobtrusive, fast and only serves web-apps, nothing else • cd ~/.pow ln ‐s /path/to/app
  • 28. rbenv • https://github.com/sstephenson/rbenv • Small, quick, doesn't modify shell commands, UNIX-way • rbenv global 1.9.2‐p290 cd /path/to/app rbenv local jruby‐1.6.4
  • 30. Ruby is not a silver bullet You should always consider different platforms and languages: Erlang, Scala, .NET and even C++
  • 31. Ruby is not a silver bullet You should always consider different platforms and languages: Erlang, Scala, .NET and even C++ Don't miss Timothy Tsvetkov's speech tomorrow

Editor's Notes