Ruby off Rails (japanese)

49
Ruby off Rails by Stoyan Zhekov Kyoto, 17-May-2008

description

Web applications development with Ruby (but without Rails)

Transcript of Ruby off Rails (japanese)

Page 1: Ruby off Rails (japanese)

Ruby off Rails

by Stoyan ZhekovKyoto, 17-May-2008

Page 2: Ruby off Rails (japanese)

自己紹介

● 名前: ストヤン ジェコフ● ブルガリア人● 3人男の子のパパ

Page 3: Ruby off Rails (japanese)

08/05/19 3

内容

● Coupling and Cohesion● ウェブアプリに必要なこと

● ORM - Sequel (簡単な見解)● Ruby ウェブエボリューション

● Enter Rack - The Middle Man● Thin, Ramaze, Tamanegi● まとめ, その他, 質問

Page 4: Ruby off Rails (japanese)

08/05/19 4

Coupling and Cohesion (1)● Cohesion - 凝集度 (ぎょうしゅうど)

http://en.wikipedia.org/wiki/Cohesion_(computer_science)● Coupling - 結合度 (けつごうど)

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

Page 5: Ruby off Rails (japanese)

08/05/19 5

Coupling and Cohesion (2)

正しいウェブアプリの組み立て方

● High cohesion– 少ない動作でたかい機能性

● Low (loosely) coupling– 簡単な入れ替え

Page 6: Ruby off Rails (japanese)

08/05/19 6

Coupling and Cohesion (3)

Google vs Amazon

Page 7: Ruby off Rails (japanese)

08/05/19 7

Coupling and Cohesion (5)

VS

Page 8: Ruby off Rails (japanese)

08/05/19 8

Railsについて

Page 9: Ruby off Rails (japanese)

08/05/19 9

Ruby on Rails● 全部セットでよかった。しかし、今は?

● Convention over configuration – いいのか?● DRY – 可能?

– Generators– Plugins– Libraries

Page 10: Ruby off Rails (japanese)

08/05/19 10

Railsなしの人生

できる?

Page 11: Ruby off Rails (japanese)

08/05/19 11

ウェブアプリに必要なこと

● データベースの使い方: ORM● Request手順: CGI env, アップロード

● ルーティング: URLとクラスの組み合わせ

● Rendering (views): rendering libraries● Sessions: persist objects or data

Page 12: Ruby off Rails (japanese)

08/05/19 12

Database ORM● Active Record ?= ActiveRecord● ActiveRecord – たくさんの問題点

– http://datamapper.org/why.html● Data Mapper – 早いけどまだ未完

– まだコンポジットキーなし

– 自分のDBドライバーが必要

● Sequel – よし。気に入ってる。

Page 13: Ruby off Rails (japanese)

08/05/19 13

ORM – Sequel (なぜ?)● Pure Ruby● Thread safe● Connection pooling● DB queries構築のためのDSL● ObjectとDBレコードの組み合わせの軽いORM● Transactions with rollback

Page 14: Ruby off Rails (japanese)

08/05/19 14

ORM – Sequel (Core)● データベースのつなげ方

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 15: Ruby off Rails (japanese)

08/05/19 15

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 16: Ruby off Rails (japanese)

08/05/19 16

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 17: Ruby off Rails (japanese)

08/05/19 17

ORM – Sequel (Model, 2)

class Person < Sequel::Model has_many :posts, :eager=>[:tags]

set_schema do primary_key :id text :name text :email foreign_key :team_id, :table => :teams end

end

Page 18: Ruby off Rails (japanese)

08/05/19 18

Evolution

Page 19: Ruby off Rails (japanese)

08/05/19 19

Ruby Web Evolution

Mongrel EventMachine

ThinWebrick Ebb

Page 20: Ruby off Rails (japanese)

08/05/19 20

Thin ウェブサーバー

● 早い – Ragel and Event Machine● クラスタリング

● Unix sockets - nginx● Rack-based – Rails, Ramaze etc.● Rackup ファイルサポート (後で)

Page 21: Ruby off Rails (japanese)

08/05/19 21

Thin + Nginx

thin start --servers 3 --socket /tmp/thinthin start --servers 3 --port 3000

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

Page 22: Ruby off Rails (japanese)

08/05/19 22

問題点

Merb Ramaze Sinatra ...

CGI Webrick Mongrel Thin

How to connect them?

Page 23: Ruby off Rails (japanese)

08/05/19 23

ソリューション - Rack

Merb Ramaze Sinatra ...

CGI Webrick Mongrel Thin

Rack – The Middle Man

Page 24: Ruby off Rails (japanese)

08/05/19 24

Rackって何?

Page 25: Ruby off Rails (japanese)

08/05/19 25

Rackって何なの?

http://rack.rubyforge.org/

By Christian Neukirchen

Page 26: Ruby off Rails (japanese)

08/05/19 26

Rackって何?

● HTTPっぽいもののRuby APIのための簡単な仕様(とその実装)– Request -> Response

● callメソッドを持ち、envを受け取り以下を返すようなオブジェクト:– a status, i.e. 200– the headers, i.e. {‘Content-Type’ => ‘text/html’}– an object that responds to each: ‘some string’

Page 27: Ruby off Rails (japanese)

08/05/19 27

これがRackだ!

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

app = RackApp.new

Page 28: Ruby off Rails (japanese)

08/05/19 28

Free Hugs

http://www.freehugscampaign.org/

Page 29: Ruby off Rails (japanese)

08/05/19 29

Hugs ウェブアプリ (1)

p 'Hug!'

Page 30: Ruby off Rails (japanese)

08/05/19 30

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 31: Ruby off Rails (japanese)

08/05/19 31

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 32: Ruby off Rails (japanese)

08/05/19 32

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 33: Ruby off Rails (japanese)

08/05/19 33

Rack Middleware

自分のuse Rack::「...」 ブロックを作れる?

class RackMiddlewareExample def initialize app @app = app end

def call env @app.call(env) endend

Page 34: Ruby off Rails (japanese)

08/05/19 34

ウェブアプリに必要なこと

● データベースの使い方(ORM): Sequel● Request手順: Rack::Request(env)● ルーティング: Rack 'map' and 'run'● Rendering/views: Tenjin, Amrita2● Sessions: Rack::Session

Page 35: Ruby off Rails (japanese)

08/05/19 35

Does it scale?

Page 36: Ruby off Rails (japanese)

08/05/19 36

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 37: Ruby off Rails (japanese)

08/05/19 37

Hugs サービス

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

Page 38: Ruby off Rails (japanese)

08/05/19 38

Rack-based フレームワークス

● Invisible – thin-based フレームワーク in 35 LOC– http://github.com/macournoyer/invisible/

● Coset – REST on Rack● Halcyon – JSON Server Framework● Merb● Sinatra● Ramaze● Rails !?

Page 39: Ruby off Rails (japanese)

08/05/19 39

RailsにもRackが必要

● RailsはRackをすでに持っている、しかし:– 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 40: Ruby off Rails (japanese)

08/05/19 40

Ramaze● 何?: モジュラーウェブアプリ フレームワーク

● どこで?: http://ramaze.net/● どうやって?: gem install ramaze● git clone http://github.com/manveru/ramaze.git● 誰が?: Michael Fellinger and Co.

Page 41: Ruby off Rails (japanese)

08/05/19 41

なぜ Ramaze?● モジュラー (low [loosely] coupling)● Rack-based● 簡単な使い方

● たくさんの例 (~25) – facebook, rapaste● フリースタイルな開発

● フレンドリーなコミュ - #ramaze● “All bugs are fixed within 48 hours of reporting.”

Page 42: Ruby off Rails (japanese)

08/05/19 42

Deployment オプションズ

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

● Ebb● Evented Mongrel● Swiftiplied Mongrel● Thin● Rack-basedなら使える

Page 43: Ruby off Rails (japanese)

08/05/19 43

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

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

Page 44: Ruby off Rails (japanese)

08/05/19 44

Ezamar

Page 45: Ruby off Rails (japanese)

08/05/19 45

本当に簡単?

%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 46: Ruby off Rails (japanese)

08/05/19 46

Ramaze使い方

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

def index smiley(':)') endend

Page 47: Ruby off Rails (japanese)

08/05/19 47

Ramaze 使い方 (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 48: Ruby off Rails (japanese)

08/05/19 48

他のStack● ORM – Sequel● ウェブサーバー – Thin + NginX● Rack Middleware● Ramaze フレームワーク

● Templates – HAML, Tenjin, Amrita2

Page 49: Ruby off Rails (japanese)

08/05/19 49

まとめ

● Railsを使うなとは言いません

● オープンマインドで

● SequelはORMに適している

● Rackを使え! – DIY framework, DIY server● Ramazeはかっこよくて、使いやすい!