one project, 3 gems
DESCRIPTION
Three handy Ruby gems inspired by the same project at Lonely Planet.TRANSCRIPT
One project,three gems
Mike WilliamsCogent Consulting
in association with
Architecture
<stuff/>“Atlas”
WORLD
Australia
Pacific
Victoria
Europe
Africa
Asia
Americas
New Zealand
NSW
MelbourneSydney
WA
Geelong
Growing Treesarboreal
(hotel)
(restaurant)
(sight)
WORLD
Australia
Pacific
Victoria
Europe
Africa
Asia
Americas
New Zealand
NSW
MelbourneSydney
WA
Geelong
arboreal
how do I select this?
Path Enumeration
@victoria = Place.find_by_name(“Victoria”)@victoria.ancestry_string#=> “-4-14-15-”
WORLD
Australia
Pacific
Victoria
Europe
Africa
Asia
Americas
New Zealand
NSW
MelbourneSydney
WA
Geelong
4
14
15
arboreal
@victoria.ancestorsSELECT * FROM places WHERE (id in (4,14,15))
WORLD
Australia
Pacific
Victoria
Europe
Africa
Asia
Americas
New Zealand
NSW
MelbourneSydney
WA
Geelong
4
14
15
arboreal
@australia = Place.find_by_name(“Australia”)
@australia.childrenSELECT * FROM places WHERE (places.parent_id = 15)
WORLD
Australia
Pacific
Victoria
Europe
Africa
Asia
Americas
New Zealand
NSW
MelbourneSydney
WA
Geelong
15
arboreal
@australia.descendantsSELECT * FROM places WHERE (places.ancestry_string like ‘-4-14-15-%’)
WORLD
Australia
Pacific
Europe
Africa
Asia
Americas
New Zealand
MelbourneSydney
WA
Geelong
“-4-14-15-”
“-4-14-15-16-”
“-4-14-15-22-”
Victoria NSW
arboreal
@australia.subtreeSELECT * FROM places WHERE (places.id = 15 OR places.ancestry_string like ‘-4-14-15-%’)
WORLD
Australia
Pacific
Europe
Africa
Asia
Americas
New Zealand
MelbourneSydney
WA
Geelong
“-4-14-15-”
“-4-14-15-16-”
“-4-14-15-22-”
Victoria NSW
arboreal
15
@australia.subtree.scope(:find, :conditions)#=> [“places.id = ? OR places.ancestry_string like ?”, 15, “-4-14-15-%”]
class Place def contained_pois Poi.scoped(:include => :place, :conditions => subtree.scope(:find, :conditions)) endend
@australia.contained_poisSELECT ... FROM pois LEFT OUTER JOIN places ON places.id = pois.place_id WHERE (places.id = 15 OR places.ancestry_string like ‘-4-14-15-%’)
arboreal
WORLD
Australia
Pacific
Victoria
Europe
Africa
Asia
Americas
New Zealand
NSW
MelbourneSydney
WA
Geelong
@australia.contained_poisSELECT ... FROM pois LEFT OUTER JOIN places ON places.id = pois.place_id WHERE (places.id = 15 OR places.ancestry_string like ‘-4-14-15-%’)
arboreal
<pois/>“Atlas”
GET http://stuff.local/places/15/pois
<pois type="array"> <poi> <created-at type="datetime">2010-08-25T23:35:59Z</created-at> <email nil="true"></email> <id type="integer">6</id> <latitude type="decimal">-37.8002389992226</latitude> <longitude type="decimal">144.901535511017</longitude> <name>Footscray Market</name> <place-id type="integer">26</place-id> <review>A frenetic covered food market.</review> <type>See</type> <updated-at type="datetime">2010-08-25T23:35:59Z</updated-at> <url nil="true"></url> </poi> <poi> <created-at type="datetime">2010-08-25T23:35:59Z</created-at> <email nil="true"></email> <id type="integer">7</id> <latitude type="decimal">-37.8020224141169</latitude> <longitude type="decimal">144.983611106873</longitude> <name>Panama Dining Room</name> <place-id type="integer">26</place-id> <review>Franco-Fitzroy pub grub and ersatz Manhattan views.</review> <type>Eat</type> <updated-at type="datetime">2010-08-25T23:35:59Z</updated-at> <url nil="true"></url> </poi> ...
<pois type="array"> <poi href="http://stuff.local/pois/6"> <name>Footscray Market</name> <type>See</type> <review>A frenetic covered food market.</review> <place href="http://stuff.local/places/26"> <name>Melbourne</name> </place> </poi> <poi href="http://stuff.local/pois/7"> <name>Panama Dining Room</name> <type>Eat</type> <review>Franco-Fitzroy pub grub and ersatz Manhattan views.</review> <place href="http://stuff.local/places/26"> <name>Melbourne</name> </place> </poi> <poi href="http://stuff.local/pois/8"> <name>Sydney Opera House</name> <type>See</type> <review/> <place href="http://stuff.local/places/17"> <name>Sydney</name> </place> </poi></pois>
# BEFORE ...xml.pois :type => “array” do @pois.each do |poi| xml.poi :href => poi_url(poi) do xml.name(poi.name) xml.type(poi.type) xml.review(poi.review) xml.place :href => place_url(poi.place) do xml.name poi.place.name end end endend
# BEFORE ...xml.pois :type => “array” do @pois.each do |poi| xml.poi :href => poi_url(poi) do xml.name(poi.name) xml.type(poi.type) xml.review(poi.review) xml.place :href => place_url(poi.place) do xml.name poi.place.name end end endend
# AFTER ...Representative::Xml.new(xml) do |r| r.list_of :pois, @pois, :item_attributes => {:href => method(:poi_url)} do r.element :name r.element :type r.element :review r.element :place, :href => method(:place_url) do r.element :name end endend
representative
# XML ...Representative::Xml.new(xml) do |r| r.list_of :pois, @pois, :item_attributes => {:href => method(:poi_url)} do r.element :name r.element :type r.element :review r.element :place, :href => method(:place_url) do r.element :name end endend
# JSON ...Representative::Json.new do |r| r.list_of :pois, @pois, :item_attributes => {:href => method(:poi_url)} do r.element :name r.element :type r.element :review r.element :place, :href => method(:place_url) do r.element :name end endend.to_s
representative
<pois type="array"> <poi href="http://stuff.local/pois/6"> <name>Footscray Market</name> <type>See</type> <review>A frenetic covered food market.</review> <place href="http://stuff.local/places/26"> <name>Melbourne</name> </place> </poi> <poi href="http://stuff.local/pois/7"> <name>Panama Dining Room</name> <type>Eat</type> <review>Franco-Fitzroy pub grub and ersatz Manhattan views.</review> <place href="http://stuff.local/places/26"> <name>Melbourne</name> </place> </poi> <poi href="http://stuff.local/pois/8"> <name>Sydney Opera House</name> <type>See</type> <review/> <place href="http://stuff.local/places/17"> <name>Sydney</name> </place> </poi></pois>
[ { "name": "Footscray Market", "type": "See", "review": "A frenetic covered food market.", "place": { "name": "Melbourne" } }, { "name": "Panama Dining Room", "type": "Eat", "review": "Franco-Fitzroy pub grub and ersatz Manhattan views.", "place": { "name": "Melbourne" } }, { "name": "Sydney Opera House", "type": "See", "review": null, "place": { "name": "Sydney" } }]
representative
<pois/>“Atlas”
<pois/>“Atlas”
somethingthat wantsPOI data
<pois/> somethingthat wantsPOI data
fake Atlas
shamrack
require ‘fakeweb’FakeWeb.register_uri(:get, “http://www.example.com/hello”, :body => “Hello World!”)
require ‘webmock’stub_request(:get, “www.example.com/hello”).to_return(:body => “Hello, World!”)
require ‘sham_rack’ShamRack.at(“www.example.com”).stub.register_resource(“/hello”, “Hello, World!”)
shamrack
It’s just Rack!
client
ShamRack
Net::HTTP
Rack app
shamrack
ShamRack.at("www.example.com").rackup douse Some::Middlewareuse Some::Other::Middlewarerun MyApp.new
end
It’s just Rack!ShamRack.at("www.example.com”) do |env|
["200 OK", { "Content-type" => "text/plain" }, "Hello, world!"
]end
shamrack
ShamRack.at("www.example.com").sinatra doget "/hello/:subject" do "Hello, #{params[:subject]}"end
end
It’s just Rack!
http://github.com/mdub/arboreal
http://github.com/mdub/representative
http://github.com/mdub/sham_rack