One project, 3 gems

Post on 28-Nov-2014

1.155 views 1 download

description

Three handy Ruby gems inspired by the same project at Lonely Planet.

Transcript of One project, 3 gems

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!