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

Wider than Rails: lightweight Ruby solutions

Avatar for anayden anayden
November 06, 2011

Wider than Rails: lightweight Ruby solutions

My RubyC 2011 talk

Avatar for anayden

anayden

November 06, 2011
Tweet

More Decks by anayden

Other Decks in Programming

Transcript

  1. Motives to travel light • Production performance • Complexity overhead

    • Learning curve • More flexibility • Self-improvement суббота, 5 ноября 11 г.
  2. Do you always need all of that? $  ls app/

    config/ db/ doc/ Gemfile lib/ log public/ Rakefile README script/ spec/ test/ tmp/ vendor/ www/ Gemfile.lock .rspec config.ru суббота, 5 ноября 11 г.
  3. Do you always need all of that? $  ls app/

    config/ db/ doc/ Gemfile lib/ log public/ Rakefile README script/ spec/ test/ tmp/ vendor/ www/ Gemfile.lock .rspec config.ru суббота, 5 ноября 11 г.
  4. Lightweight plan • Replace components of your framework • Inject

    lightweight tools • Migrate to a different platform • Don't forget to be consistent суббота, 5 ноября 11 г.
  5. 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 суббота, 5 ноября 11 г.
  6. 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 суббота, 5 ноября 11 г.
  7. 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 суббота, 5 ноября 11 г.
  8. 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) суббота, 5 ноября 11 г.
  9. 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 суббота, 5 ноября 11 г.
  10. 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(){ ... }); суббота, 5 ноября 11 г.
  11. 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!) суббота, 5 ноября 11 г.
  12. 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 суббота, 5 ноября 11 г.
  13. Rack App Example class ServerLoad def call(env) [200, {"Content-Type" =>

    "text/plain"}, ["uptime | cut -f 11 -d ' '"]] end end суббота, 5 ноября 11 г.
  14. 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 суббота, 5 ноября 11 г.
  15. 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 суббота, 5 ноября 11 г.
  16. 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 суббота, 5 ноября 11 г.
  17. 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 Sinatra суббота, 5 ноября 11 г.
  18. 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 суббота, 5 ноября 11 г.
  19. Padrino blog 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 $ padrino g project sample_blog -t shoulda -e haml \ -c sass -s jquery -d activerecord -b суббота, 5 ноября 11 г.
  20. 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 суббота, 5 ноября 11 г.
  21. 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 суббота, 5 ноября 11 г.
  22. 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 суббота, 5 ноября 11 г.
  23. 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 суббота, 5 ноября 11 г.
  24. Ruby is not a silver bullet You should always consider

    different platforms and languages: Erlang, Scala, .NET and even C++ суббота, 5 ноября 11 г.
  25. 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 суббота, 5 ноября 11 г.