2. Table of content
● Coupling and Cohesion
● Common needs for various web apps
● ORM - Sequel (short overview)
● Ruby Web Evolution
● Enter Rack - The Middle Man
● Thin, Ramaze, Tamanegi
● Summary, Extras, Questions
08/05/19 2
4. Coupling and Cohesion (2)
Applications should be composed of components
that show:
● High cohesion
– doing small number of things and do them well
● Low (loosely) coupling
– easy replace any component with another one
08/05/19 4
10. Common needs for various web apps
● Database handling: ORM
● Request processing: CGI env, uploads
● Routing/dispatching: map URLs to classes
● Rendering/views: rendering libraries
● Sessions: persist objects or data
08/05/19 10
11. Database ORM
● Active Record ?= ActiveRecord
● ActiveRecord – a lot of problems
– http://datamapper.org/why.html
● Data Mapper – fast, but not ready
– No composite keys (when I started using it)
– Have it's own database drivers
● Sequel – good, I like it
08/05/19 11
12. ORM – Sequel (Why?)
● Pure Ruby
● Thread safe
● Connection pooling
● DSL for constructing DB queries
● Lightweight ORM layer for mapping records to
Ruby objects
● Transactions with rollback
08/05/19 12
13. ORM – Sequel (Core)
● Database Connect
require 'sequel'
DB = Sequel.open 'sqlite:///blog.db'
DB = Sequel.open 'postgres://cico:12345@localhost:5432/mydb'
DB = Sequel.open(quot;postgres://postgres:postgres@localhost/my_dbquot;,
:max_connections => 10, :logger => Logger.new('log/db.log'))
08/05/19 13
14. ORM – Sequel (Core, 2)
DB << quot;CREATE TABLE users (name VARCHAR(255) NOT NULL)quot;
DB.fetch(quot;SELECT name FROM usersquot;) do |row|
p r[:name]
end
dataset = DB[:managers].where(:salary => 50..100).order(:name, :department)
paginated = dataset.paginate(1, 10) # first page, 10 rows per page
paginated.page_count #=> number of pages in dataset
paginated.current_page #=> 1
08/05/19 14
15. ORM – Sequel (Model)
class Post < Sequel::Model(:my_posts)
set_primary_key [:category, :title]
belongs_to :author
has_many :comments
has_and_belongs_to_many :tags
after_create do
set(:created_at => Time.now)
end
end
08/05/19 15
16. ORM – Sequel (Model, 2)
class Person < Sequel::Model
one_to_many :posts, :eager=>[:tags]
set_schema do
primary_key :id
text :name
text :email
foreign_key :team_id, :table => :teams
end
end
08/05/19 16
19. Thin web server
● Fast – Ragel and Event Machine
● Clustering
● Unix sockets (the only one I found) - nginx
● Rack-based – Rails, Ramaze etc.
● Rackup files support (follows)
05/19/08 19
24. What IS Rack?
http://rack.rubyforge.org/
By Christian Neukirchen
05/19/08 24
25. WHAT is Rack?
● Specification (and implementation) of a minimal
abstract Ruby API that models HTTP
– Request -> Response
● An object that responds to call and accepts one
argument: env, and returns:
– a status, i.e. 200
– the headers, i.e. {‘Content-Type’ => ‘text/html’}
– an object that responds to each: ‘some string’
05/19/08 25
26. This is Rack!
class RackApp
def call(env)
[ 200, {quot;Content-Typequot; => quot;text/plainquot;}, quot;Hi!quot;]
end
end
app = RackApp.new
05/19/08 26
32. Rack Middleware
Can I create my own use Rack::... blocks?
class RackMiddlewareExample
def initialize app
@app = app
end
def call env
@app.call(env)
end
end
05/19/08 32
33. Common needs for various web apps
● Database handling: ORM Sequel
● Request processing: Rack::Request(env)
● Routing/dispatching: Rack 'map' and 'run'
● Rendering/views: Tenjin, Amrita2
● Sessions: Rack::Session
05/19/08 33
37. Rack-based frameworks
● Invisible – thin-based framework in 35 LOC
– http://github.com/macournoyer/invisible/
● Coset – REST on Rack
● Halcyon – JSON Server Framework
● Merb
● Sinatra
● Ramaze
● Rails !?
05/19/08 37
38. Rack coming to Rails
● Rails already have Rack, but:
– raw req -> rack env -> Rack::Request ->CGIWrapper ->
CgiRequest
● Ezra Zygmuntowicz (merb)'s repo on github
– http://github.com/ezmobius/rails
– raw req -> rack env -> ActionController::RackRequest
– ./script/rackup -s thin -c 5 -e production
05/19/08 38
39. Ramaze
● What: A modular web application framework
● Where: http://ramaze.net/
● How: gem install ramaze
● git clone http://github.com/manveru/ramaze.git
● Who: Michael Fellinger and Co.
05/19/08 39
40. Why Ramaze?
● Modular (low [loosely] coupling)
● Rack-based
● Easy to use
● A lot of examples (~25) – facebook, rapaste
● Free style of development
● Friendly community - #ramaze
● “All bugs are fixed within 48 hours of reporting.”
05/19/08 40
41. Deployment options
● CGI ● Ebb
● FastCGI ● Evented Mongrel
● LiteSpeed ● Swiftiplied Mongrel
● Mongrel ● Thin
● SCGI ● Whatever comes along
● Webrick and fits into the Rack
05/19/08 41
44. Easy to use?
%w(rubygems ramaze).each {|dep| require dep}
class MainController < Ramaze::Controller
def index; quot;Hiquot; end
end
class HugsController < Ramaze::Controller
map '/hug'
def index; quot;Hug!quot; end
end
Ramaze.start :adapter => :thin, :port => 3000
05/19/08 44
45. Ramaze Usage
class SmileyController <
Ramaze::Controller
map '/smile'
helper :smiley
def index
smiley(':)')
end
end
05/19/08 45
46. Ramaze Usage (2)
module Ramaze
module Helper
module SmileyHelper
FACES = {
':)' => '/images/smile.png',
';)' => '/images/twink.png'}
REGEXP = Regexp.union(*FACES.keys)
def smiley(string)
string.gsub(REGEXP) { FACES[$1] }
end
end
end
end
05/19/08 46
47. Alternative Stack
● ORM – Sequel
● Web server – Thin + NginX
● Rack Middleware
● Ramaze framework
● Templates – HAML, Tenjin, Amrita2
05/19/08 47
48. Summary
● Not trying to tell you to not use Rails
● Just keep your mind open
● Sequel is good ORM
● Use Rack – DIY framework, DIY server
● Ramaze is cool and easy to use
05/19/08 48