Top Banner
Ruby off Rails by Stoyan Zhekov Kyoto, 17-May-2008
48

Ruby off Rails (english)

May 17, 2015

Download

Technology

Stoyan Zhekov

Web applications development with Ruby (but without Rails)
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Ruby off Rails (english)

Ruby off Rails

by Stoyan ZhekovKyoto, 17-May-2008

Page 2: Ruby off Rails (english)

08/05/19 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

Page 3: Ruby off Rails (english)

08/05/19 3

Coupling and Cohesion (1)● Cohesion

http://en.wikipedia.org/wiki/Cohesion_(computer_science)● Coupling

http://en.wikipedia.org/wiki/Coupling_(computer_science)

Page 4: Ruby off Rails (english)

08/05/19 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

Page 5: Ruby off Rails (english)

08/05/19 5

Coupling and Cohesion (3)

Google vs Amazon

Page 6: Ruby off Rails (english)

08/05/19 6

Coupling and Cohesion (4)

VS

Page 7: Ruby off Rails (english)

08/05/19 7

What about Rails?

Page 8: Ruby off Rails (english)

08/05/19 8

Ruby on Rails● Full Stack – was good. Now?● Convention over configuration – good?● DRY – possible?

– Generators– Plugins– Libraries

Page 9: Ruby off Rails (english)

08/05/19 9

Life without Rails

Is it possible?

Page 10: Ruby off Rails (english)

08/05/19 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

Page 11: Ruby off Rails (english)

08/05/19 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

Page 12: Ruby off Rails (english)

08/05/19 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

Page 13: Ruby off Rails (english)

08/05/19 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("postgres://postgres:postgres@localhost/my_db", :max_connections => 10, :logger => Logger.new('log/db.log'))

Page 14: Ruby off Rails (english)

08/05/19 14

ORM – Sequel (Core, 2)

DB << "CREATE TABLE users (name VARCHAR(255) NOT NULL)"

DB.fetch("SELECT name FROM users") 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 pagepaginated.page_count #=> number of pages in datasetpaginated.current_page #=> 1

Page 15: Ruby off Rails (english)

08/05/19 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

Page 16: Ruby off Rails (english)

08/05/19 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 endend

Page 17: Ruby off Rails (english)

08/05/19 17

Evolution

Page 18: Ruby off Rails (english)

05/19/08 18

Ruby Web Evolution

Mongrel EventMachine

ThinWebrick Ebb

Page 19: Ruby off Rails (english)

05/19/08 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)

Page 20: Ruby off Rails (english)

05/19/08 20

Thin + Nginx

thin start --servers 3 --socket /tmp/thinthin start --servers 3 –post 3000

# nginx.confupstream backend { fair; server unix:/tmp/thin.0.sock; server unix:/tmp/thin.1.sock; server unix:/tmp/thin.2.sock;}

Page 21: Ruby off Rails (english)

05/19/08 21

The problem

Merb Ramaze Sinatra ...

CGI Webrick Mongrel Thin

How to connect them?

Page 22: Ruby off Rails (english)

05/19/08 22

The solution - Rack

Merb Ramaze Sinatra ...

CGI Webrick Mongrel Thin

Rack – The Middle Man

Page 23: Ruby off Rails (english)

05/19/08 23

What is Rack?

Page 24: Ruby off Rails (english)

05/19/08 24

What IS Rack?

http://rack.rubyforge.org/

By Christian Neukirchen

Page 25: Ruby off Rails (english)

05/19/08 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’

Page 26: Ruby off Rails (english)

05/19/08 26

This is Rack!

class RackApp def call(env) [ 200, {"Content-Type" => "text/plain"}, "Hi!"] endend

app = RackApp.new

Page 27: Ruby off Rails (english)

05/19/08 27

Free Hugs

http://www.freehugscampaign.org/

Page 28: Ruby off Rails (english)

05/19/08 28

Hugs Application

p 'Hug!'

Page 29: Ruby off Rails (english)

05/19/08 29

ruby hugs.rb

%w(rubygems rack).each { |dep| require dep }

class HugsApp def call(env) [ 200, {"Content-Type" => "text/plain"}, "Hug!"] endend

Rack::Handler::Mongrel.run(HugsApp.new, :Port => 3000)

Page 30: Ruby off Rails (english)

05/19/08 30

Rack::Builderrequire 'hugs'app = Rack::Builder.new { use Rack::Static, :urls => ["/css", "/images"], :root => "public" use Rack::CommonLogger use Rack::ShowExceptions map "/" do run lambda { [200, {"Content-Type" => "text/plain"}, ["Hi!"]] } end map "/hug" do run HugsApp.new end}

Rack::Handler::Thin.run app, :Port => 3000

Page 31: Ruby off Rails (english)

05/19/08 31

Rack Building Blocks● request = Rack::Request.new(env)

– request.get?● response = Rack::Response.new('Hi!')

– response.set_cookie('sess-id', 'abcde')● Rack::URLMap● Rack::Session● Rack::Auth::Basic● Rack::File

Page 32: Ruby off Rails (english)

05/19/08 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) endend

Page 33: Ruby off Rails (english)

05/19/08 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

Page 34: Ruby off Rails (english)

05/19/08 34

Does it scale?

Page 35: Ruby off Rails (english)

05/19/08 35

rackup hugs.ru

require 'hugs'app = Rack::Builder.new {use Rack::Static, :urls => ["/css", "/images"], :root => "public" map "/" do run lambda { [200, {"Content-Type" => "text/plain"}, ["Hi!"]] }end map "/hug" do run HugsApp.newend}Rack::Handler::Thin.run app, :Port => 3000

Page 36: Ruby off Rails (english)

05/19/08 36

Hugs Service● rackup -s webrick -p 3000 hugs.ru● thin start --servers 3 -p 3000 -R hugs.ru● SCGI● FastCGI● Litespeed● ....

Page 37: Ruby off Rails (english)

05/19/08 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 !?

Page 38: Ruby off Rails (english)

05/19/08 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

Page 39: Ruby off Rails (english)

05/19/08 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.

Page 40: Ruby off Rails (english)

05/19/08 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.”

Page 41: Ruby off Rails (english)

05/19/08 41

Deployment options

● CGI● FastCGI● LiteSpeed● Mongrel● SCGI● Webrick

● Ebb● Evented Mongrel● Swiftiplied Mongrel● Thin● Whatever comes along

and fits into the Rack

Page 42: Ruby off Rails (english)

05/19/08 42

Templating engines● Amrita2● Builder● Erubis● Ezmar● Haml● Liquid● Markaby

● RedCloth● Remarkably● Sass● Tagz● Tenjin● XSLT

Page 43: Ruby off Rails (english)

05/19/08 43

Ezamar

Page 44: Ruby off Rails (english)

05/19/08 44

Easy to use?

%w(rubygems ramaze).each {|dep| require dep}

class MainController < Ramaze::Controller def index; "Hi" endend

class HugsController < Ramaze::Controller map '/hug' def index; "Hug!" endend

Ramaze.start :adapter => :thin, :port => 3000

Page 45: Ruby off Rails (english)

05/19/08 45

Ramaze Usage

class SmileyController < Ramaze::Controller map '/smile' helper :smiley

def index smiley(':)') endend

Page 46: Ruby off Rails (english)

05/19/08 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 endend

Page 47: Ruby off Rails (english)

05/19/08 47

Alternative Stack● ORM – Sequel● Web server – Thin + NginX● Rack Middleware● Ramaze framework● Templates – HAML, Tenjin, Amrita2

Page 48: Ruby off Rails (english)

05/19/08 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