Ruby off Rails (english)

6,200
-1

Published on

Web applications development with Ruby (but without Rails)

Published in: Technology
0 Comments
4 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
6,200
On Slideshare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
56
Comments
0
Likes
4
Embeds 0
No embeds

No notes for slide

Ruby off Rails (english)

  1. 1. Ruby off Rails by Stoyan Zhekov Kyoto, 17-May-2008
  2. 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
  3. 3. Coupling and Cohesion (1) ● Cohesion http://en.wikipedia.org/wiki/Cohesion_(computer_science) ● Coupling http://en.wikipedia.org/wiki/Coupling_(computer_science) 08/05/19 3
  4. 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
  5. 5. Coupling and Cohesion (3) Google vs Amazon 08/05/19 5
  6. 6. Coupling and Cohesion (4) VS 08/05/19 6
  7. 7. What about Rails? 08/05/19 7
  8. 8. Ruby on Rails ● Full Stack – was good. Now? ● Convention over configuration – good? ● DRY – possible? – Generators – Plugins – Libraries 08/05/19 8
  9. 9. Life without Rails Is it possible? 08/05/19 9
  10. 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. 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. 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. 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. 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. 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. 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
  17. 17. Evolution 08/05/19 17
  18. 18. Ruby Web Evolution Webrick Mongrel Event Thin Ebb Machine 05/19/08 18
  19. 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
  20. 20. Thin + Nginx thin start --servers 3 --socket /tmp/thin thin start --servers 3 –post 3000 # nginx.conf upstream backend { fair; server unix:/tmp/thin.0.sock; server unix:/tmp/thin.1.sock; server unix:/tmp/thin.2.sock; } 05/19/08 20
  21. 21. The problem Merb Ramaze Sinatra ... How to connect them? CGI Webrick Mongrel Thin 05/19/08 21
  22. 22. The solution - Rack Merb Ramaze Sinatra ... Rack – The Middle Man CGI Webrick Mongrel Thin 05/19/08 22
  23. 23. What is Rack? 05/19/08 23
  24. 24. What IS Rack? http://rack.rubyforge.org/ By Christian Neukirchen 05/19/08 24
  25. 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. 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
  27. 27. Free Hugs http://www.freehugscampaign.org/ 05/19/08 27
  28. 28. Hugs Application p 'Hug!' 05/19/08 28
  29. 29. ruby hugs.rb %w(rubygems rack).each { |dep| require dep } class HugsApp def call(env) [ 200, {quot;Content-Typequot; => quot;text/plainquot;}, quot;Hug!quot;] end end Rack::Handler::Mongrel.run(HugsApp.new, :Port => 3000) 05/19/08 29
  30. 30. Rack::Builder require 'hugs' app = Rack::Builder.new { use Rack::Static, :urls => [quot;/cssquot;, quot;/imagesquot;], :root => quot;publicquot; use Rack::CommonLogger use Rack::ShowExceptions map quot;/quot; do run lambda { [200, {quot;Content-Typequot; => quot;text/plainquot;}, [quot;Hi!quot;]] } end map quot;/hugquot; do run HugsApp.new end } Rack::Handler::Thin.run app, :Port => 3000 05/19/08 30
  31. 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 05/19/08 31
  32. 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. 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
  34. 34. Does it scale? 05/19/08 34
  35. 35. rackup hugs.ru require 'hugs' app = Rack::Builder.new { use Rack::Static, :urls => [quot;/cssquot;, quot;/imagesquot;], :root => quot;publicquot; map quot;/quot; do run lambda { [200, {quot;Content-Typequot; => quot;text/plainquot;}, [quot;Hi!quot;]] } end map quot;/hugquot; do run HugsApp.new end } Rack::Handler::Thin.run app, :Port => 3000 05/19/08 35
  36. 36. Hugs Service ● rackup -s webrick -p 3000 hugs.ru ● thin start --servers 3 -p 3000 -R hugs.ru ● SCGI ● FastCGI ● Litespeed ● .... 05/19/08 36
  37. 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. 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. 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. 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. 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
  42. 42. Templating engines ● Amrita2 ● RedCloth ● Builder ● Remarkably ● Erubis ● Sass ● Ezmar ● Tagz ● Haml ● Tenjin ● Liquid ● XSLT ● Markaby 05/19/08 42
  43. 43. Ezamar 05/19/08 43
  44. 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. 45. Ramaze Usage class SmileyController < Ramaze::Controller map '/smile' helper :smiley def index smiley(':)') end end 05/19/08 45
  46. 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. 47. Alternative Stack ● ORM – Sequel ● Web server – Thin + NginX ● Rack Middleware ● Ramaze framework ● Templates – HAML, Tenjin, Amrita2 05/19/08 47
  48. 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
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×