3. Less code
=
Easier to maintain
=
(often)
Faster
суббота, 5 ноября 11 г.
4. Motives to travel light
• Production performance
• Complexity overhead
• Learning curve
• More flexibility
• Self-improvement
суббота, 5 ноября 11 г.
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
суббота, 5 ноября 11 г.
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
суббота, 5 ноября 11 г.
7. Lightweight plan
• Replace components of your framework
• Inject lightweight tools
• Migrate to a different platform
• Don't forget to be consistent
суббота, 5 ноября 11 г.
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
суббота, 5 ноября 11 г.
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
суббота, 5 ноября 11 г.
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
суббота, 5 ноября 11 г.
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)
суббота, 5 ноября 11 г.
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
суббота, 5 ноября 11 г.
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(){ ... });
суббота, 5 ноября 11 г.
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!)
суббота, 5 ноября 11 г.
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
суббота, 5 ноября 11 г.
17. Rack App Example
class ServerLoad
def call(env)
[200, {"Content-Type" => "text/plain"}, ["uptime | cut -f 11 -d ' '"]]
end
end
суббота, 5 ноября 11 г.
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
суббота, 5 ноября 11 г.
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
суббота, 5 ноября 11 г.
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
суббота, 5 ноября 11 г.
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
суббота, 5 ноября 11 г.
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
суббота, 5 ноября 11 г.
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
суббота, 5 ноября 11 г.
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
суббота, 5 ноября 11 г.
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
суббота, 5 ноября 11 г.
26. Tools
They don't need to be huge and slow
суббота, 5 ноября 11 г.
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
суббота, 5 ноября 11 г.
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
суббота, 5 ноября 11 г.
30. Ruby is not a silver
bullet
You should always consider different platforms and
languages: Erlang, Scala, .NET and even C++
суббота, 5 ноября 11 г.
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
суббота, 5 ноября 11 г.
32. Questions?
alexey.nayden@evilmartians.com
суббота, 5 ноября 11 г.