126
Building your rst MongoDB Acaon

Build your first MongoDB App in Ruby @ StrangeLoop 2013

Embed Size (px)

DESCRIPTION

A workshop given at StrangeLoop 2013 teaching you how to build your first MongoDB application in Ruby

Citation preview

Page 1: Build your first MongoDB App in Ruby @ StrangeLoop 2013

Building your rst MongoDB Acaon

Page 2: Build your first MongoDB App in Ruby @ StrangeLoop 2013

AgdaIntroduction to MongoDB

MongoDB Fundamentals

Running MongoDB

Schema Design

Ruby & Sinatra Crash Course

Building Our First App

Page 4: Build your first MongoDB App in Ruby @ StrangeLoop 2013

Iroducon to

mongodb

Page 5: Build your first MongoDB App in Ruby @ StrangeLoop 2013

What Is MongoDB?

Page 6: Build your first MongoDB App in Ruby @ StrangeLoop 2013

*Document

*Open source

*High performance

*Horizontally scalable

*Full featured

MongoDB is a ___________ database

Page 7: Build your first MongoDB App in Ruby @ StrangeLoop 2013

* Not for .PDF & .DOC files

* A document is essentially an associative array

* Document == JSON object

* Document == PHP Array

* Document == Python Dict

* Document == Ruby Hash

* etc

Documt Database

Page 8: Build your first MongoDB App in Ruby @ StrangeLoop 2013

*MongoDB is an open source project

*On GitHub

* Licensed under the AGPL

*Commercial licenses available

*Contributions welcome

Op Source

Page 9: Build your first MongoDB App in Ruby @ StrangeLoop 2013

* Written in C++

* Extensive use of memory-mapped files i.e. read-through write-through memory caching.

* Runs nearly everywhere

* Data serialized as BSON (fast parsing)

* Full support for primary & secondary indexes

* Document model = less work

High Pfoance

Page 10: Build your first MongoDB App in Ruby @ StrangeLoop 2013

Hozoal Scable

Page 11: Build your first MongoDB App in Ruby @ StrangeLoop 2013

* Ad Hoc queries

* Real time aggregation

* Rich query capabilities

* Traditionally consistent

* Geospatial features

* Support for most programming languages

* Flexible schema

Full Ftured

Page 12: Build your first MongoDB App in Ruby @ StrangeLoop 2013

Depth of Functionality

Scal

abili

ty &

Per

form

ance

Memcached

MongoDB

RDBMS

Database ndscape

Page 13: Build your first MongoDB App in Ruby @ StrangeLoop 2013

tp://w.mongodb.org/downloads

Page 14: Build your first MongoDB App in Ruby @ StrangeLoop 2013

What is a Record?

Page 15: Build your first MongoDB App in Ruby @ StrangeLoop 2013

K → Value* One-dimensional storage

* Single value is a blob

* Query on key only

* No schema

* Value cannot be updated, only replaced

Key Blob

Page 16: Build your first MongoDB App in Ruby @ StrangeLoop 2013

Raonal* Two-dimensional storage

(tuples)

* Each field contains a single value

* Query on any field

* Very structured schema (table)

* In-place updates

* Normalization process requires many tables, joins, indexes, and poor data locality

Primary Key

Page 17: Build your first MongoDB App in Ruby @ StrangeLoop 2013

Documt* N-dimensional storage

* Each field can contain 0, 1, many, or embedded values

* Query on any field & level

* Flexible schema

* Inline updates *

* Embedding related data has optimal data locality, requires fewer indexes, has better performance

_id

Page 18: Build your first MongoDB App in Ruby @ StrangeLoop 2013

Running

Mongodb

Page 19: Build your first MongoDB App in Ruby @ StrangeLoop 2013

MongoD

Page 20: Build your first MongoDB App in Ruby @ StrangeLoop 2013

Mongo Shl

Page 21: Build your first MongoDB App in Ruby @ StrangeLoop 2013

user = { username: 'fred.jones', first_name: 'fred', last_name: 'jones',}

Sta wh an object (or ay, hash, dict, c)

Page 22: Build your first MongoDB App in Ruby @ StrangeLoop 2013

> db.users.insert(user)

Inst e record

No collection creation needed

Page 23: Build your first MongoDB App in Ruby @ StrangeLoop 2013

> db.users.findOne()

{

"_id" : ObjectId("50804d0bd94ccab2da652599"),

"username" : "fred.jones",

"first_name" : "fred",

"last_name" : "jones"

}

Quying for e us

Page 24: Build your first MongoDB App in Ruby @ StrangeLoop 2013

* _id is the primary key in MongoDB

*Automatically indexed

*Automatically created as an ObjectId if not provided

*Any unique immutable value could be used

_id

Page 25: Build your first MongoDB App in Ruby @ StrangeLoop 2013

*ObjectId is a special 12 byte value

*Guaranteed to be unique across your cluster

* ObjectId("50804d0bd94ccab2da652599") |-------------||---------||-----||----------| ts mac pid inc

ObjectId

Page 26: Build your first MongoDB App in Ruby @ StrangeLoop 2013

SchaDesign

Page 27: Build your first MongoDB App in Ruby @ StrangeLoop 2013

Tdaonal scha design Focuses on data stoge

Page 28: Build your first MongoDB App in Ruby @ StrangeLoop 2013

Documt scha design

Focuses on use

Page 29: Build your first MongoDB App in Ruby @ StrangeLoop 2013

4 Building blocksof Documt Design

Page 30: Build your first MongoDB App in Ruby @ StrangeLoop 2013

exibi* Choices for schema design

* Each record can have different fields

* Field names consistent for programming

* Common structure can be enforced by application

* Easy to evolve as needed

Page 31: Build your first MongoDB App in Ruby @ StrangeLoop 2013

Ays* Each field can be:

* Absent

* Set to null

* Set to a single value

* Set to an array of many values

* Query for any matching value

* Can be indexed and each value in the array is in the index

Page 32: Build your first MongoDB App in Ruby @ StrangeLoop 2013

beed Documts* An acceptable value is a

document

* Nested documents provide structure

* Query any field at any level

* Can be indexed

Page 33: Build your first MongoDB App in Ruby @ StrangeLoop 2013

*Object in your model

*Associations with other entities

Aßociaon

Referencing (Relational) Embedding (Document)

has_one embeds_one

belongs_to embedded_in

has_many embeds_many

has_and_belongs_to_many

MongoDB has both referencing and embedding for universal coverage

Page 34: Build your first MongoDB App in Ruby @ StrangeLoop 2013

Excise 1:Mod a busineß card

Page 35: Build your first MongoDB App in Ruby @ StrangeLoop 2013

Busineß Card

Page 36: Build your first MongoDB App in Ruby @ StrangeLoop 2013

Contacts

{ “_id”: 2, “name”: “Steven Jobs”, “title”: “VP, New Product Development”, “company”: “Apple Computer”, “phone”: “408-996-1010”, “address_id”: 1}

RcingAddresses

{ “_id”: 1, “street”: “10260 Bandley Dr”, “city”: “Cupertino”, “state”: “CA”, “zip_code”: ”95014”, “country”: “USA”}

Page 37: Build your first MongoDB App in Ruby @ StrangeLoop 2013

Contacts

{ “_id”: 2, “name”: “Steven Jobs”, “title”: “VP, New Product Development”, “company”: “Apple Computer”, “address”: { “street”: “10260 Bandley Dr”, “city”: “Cupertino”, “state”: “CA”, “zip_code”: ”95014”, “country”: “USA” }, “phone”: “408-996-1010”}

being

Page 38: Build your first MongoDB App in Ruby @ StrangeLoop 2013

Excise 2:Store a busineß card

Page 39: Build your first MongoDB App in Ruby @ StrangeLoop 2013

Contactsdb.contacts.insert({ “_id”: 2, “name”: “Steven Jobs”, “title”: “VP, New Product Development”, “company”: “Apple Computer”, “phone”: “408-996-1010”, “address_id”: 1})

Insng wh RceAddressesdb.addresses.insert({ “_id”: 1, “street”: “10260 Bandley Dr”, “city”: “Cupertino”, “state”: “CA”, “zip_code”: ”95014”, “country”: “USA”})

Page 40: Build your first MongoDB App in Ruby @ StrangeLoop 2013

Excise 3:Re a busineß card

Page 41: Build your first MongoDB App in Ruby @ StrangeLoop 2013

Contactsc = db.contacts.findOne({ “name”: “Steven Jobs”,})

Quying wh RceAddressesdb.addresses.findOne({ “_id”: c.address_id, “street”: “10260 Bandley Dr”, “city”: “Cupertino”, “state”: “CA”, “zip_code”: ”95014”, “country”: “USA”})

Page 42: Build your first MongoDB App in Ruby @ StrangeLoop 2013

Building aMongoDBAcaon

Page 43: Build your first MongoDB App in Ruby @ StrangeLoop 2013

MongoDB has nave bindings

for nr all nguages

Page 44: Build your first MongoDB App in Ruby @ StrangeLoop 2013

Official Support for 12 languages

Community drivers for tons more

Drivers connect to mongo servers

Drivers translate BSON into native types

mongo shell is not a driver, but works like one in some ways

Installed using typical means (npm, pecl, gem, pip)

MongoDB dvs

Page 45: Build your first MongoDB App in Ruby @ StrangeLoop 2013
Page 46: Build your first MongoDB App in Ruby @ StrangeLoop 2013
Page 47: Build your first MongoDB App in Ruby @ StrangeLoop 2013

Building an a in Ruby?Had to pick a language

Sinatra is very minimal and approachable

Wanted to focus on MongoDB interaction

Ruby gems are awesome

Works well on Windows, OS X & Linux

Seemed like a good idea at the time

Page 48: Build your first MongoDB App in Ruby @ StrangeLoop 2013

RubyCsh Course

Page 49: Build your first MongoDB App in Ruby @ StrangeLoop 2013

hing is an object1.class'a'.class:z.class

class Foo end

Foo.classFoo.new.class

# => Fixnum# => String# => Symbol

# => Class

# => Foo

Page 50: Build your first MongoDB App in Ruby @ StrangeLoop 2013

StructureMethod

Class

Invocation

def do_stuff(thing) thing.do_the_stuffend

class TheThing def do_the_stuff puts "Stuff was done!" endend

do_stuff(TheThing.new)

Page 51: Build your first MongoDB App in Ruby @ StrangeLoop 2013

Stngsname = 'World' # => "World"

"Hello, #{name}" # => "Hello, World"

'Hello, #{name}' # => "Hello, \#{name}"

Page 52: Build your first MongoDB App in Ruby @ StrangeLoop 2013

Numbs1 + 1 # => 21 + 1.1 # => 2.16 * 7 # => 426 ** 7 # => 279936

Math.sqrt(65536) # => 256.01.class # => Fixnum(2 ** 42).class # => Fixnum(2 ** 64).class # => Bignum1.1.class # => Float

Page 53: Build your first MongoDB App in Ruby @ StrangeLoop 2013

AysArray.newArray.new(3)[]

a = [1,2,3]a[0] = 'one'aa[-1]a[1..2]

# => []# => [nil, nil, nil]# => []

# => [1, 2, 3]# => "one"# => ["one", 2, 3]# => 3# => [2, 3]

Page 54: Build your first MongoDB App in Ruby @ StrangeLoop 2013

HashesHash.new {} h = {1 => "one", 2 => "two"}h[1] h["1"]h[:one] = "einz"h[:one]

h.keysh.values

# => {}# => {}

# => "one"# => nil# => "einz"# => "einz"

# => [1, 2, :one]# => ["one", "two", "einz"]

Page 55: Build your first MongoDB App in Ruby @ StrangeLoop 2013

Vaables & NamesCamelCased # Classes, moduleswith_underscores # methods, local variables@instance_variable@@class_variable$GLOBAL_VARIABLE

Page 56: Build your first MongoDB App in Ruby @ StrangeLoop 2013

Corol Structuresif condition # ...elsif other_condition # ...end

unless condition # ...end

while# ...end

Page 57: Build your first MongoDB App in Ruby @ StrangeLoop 2013
Page 58: Build your first MongoDB App in Ruby @ StrangeLoop 2013

Sinat is...not Rails

not a framework

a DSL for quickly creating web applications in Ruby with minimal effort

Page 59: Build your first MongoDB App in Ruby @ StrangeLoop 2013

Hlo World

# myapp.rbrequire 'sinatra'

get '/' do 'Hello world!'end

Page 60: Build your first MongoDB App in Ruby @ StrangeLoop 2013

TP AconsIn Sinatra, a route is an HTTP method paired with a URL-matching pattern.

Each route is associated with a block:

get '/' do .. show something ..end

post '/' do .. create something ..end

put '/' do .. replace something ..end

delete '/' do .. annihilate something ..end

Page 61: Build your first MongoDB App in Ruby @ StrangeLoop 2013

RoesRoutes are matched in the order they are defined. The first route that matches the request is invoked.

Route patterns may include named parameters, accessible via the params hash:

get '/hello/:name' do # matches "GET /hello/foo" and "GET /hello/bar" # params[:name] is 'foo' or 'bar' "Hello #{params[:name]}!"end

#You can also access named parameters via block parameters:get '/hello/:name' do |n| "Hello #{n}!"end

Page 62: Build your first MongoDB App in Ruby @ StrangeLoop 2013

SptRoute patterns may also include splat (or wildcard) parameters, accessible via the params[:splat] array:

get '/say/*/to/*' do # matches /say/hello/to/world params[:splat] # => ["hello", "world"]end

get '/download/*.*' do # matches /download/path/to/file.xml params[:splat] # => ["path/to/file", "xml"]end

Page 63: Build your first MongoDB App in Ruby @ StrangeLoop 2013

Building our A in Ruby

Page 64: Build your first MongoDB App in Ruby @ StrangeLoop 2013

Iroducing e mieu a

Page 65: Build your first MongoDB App in Ruby @ StrangeLoop 2013

pre-popung our database

Page 66: Build your first MongoDB App in Ruby @ StrangeLoop 2013

Download & Impo e vues⇒ curl -L http://j.mp/StrangeLoopVenues | \ mongoimport -d milieu -c venues

wget http://c.spf13.com/dl/StrangeLoopVenues.json mongoimport -d milieu -c venues StrangeLoopVenues.json

Database

Collection

Page 67: Build your first MongoDB App in Ruby @ StrangeLoop 2013

Mongo Shl

Page 68: Build your first MongoDB App in Ruby @ StrangeLoop 2013

L’s lk at e vues> use milieuswitched to db milieu

> db.venues.count()50

Database

Page 69: Build your first MongoDB App in Ruby @ StrangeLoop 2013

L’s lk at e vues> db.venues.findOne(){ "_id" : ObjectId("52335163695c9d31c2000001"), "location" : { "address" : "1820 Market St", "distance" : 85, "postalCode" : "63103", "city" : "Saint Louis", "state" : "MO", "country" : "United States", "cc" : "US", "geo" : [ -90.20761747801353, 38.62893438211461 ] }, "name" : "St. Louis Union Station Hotel- A DoubleTree by Hilton", "contact" : { "phone" : "3146215262", "formattedPhone" : "(314) 621-5262", "url" : "http://www.stlunionstationhotel.com" }, "stats" : { "checkinsCount" : 0, "usersCount" : 0 }}

Page 70: Build your first MongoDB App in Ruby @ StrangeLoop 2013

Crng a Geo index> db.venues.ensureIndex({ 'location.geo' : '2d'})> db.venues.getIndexes()[ { "v" : 1, "key" : { "_id" : 1 }, "ns" : "milieu.venues", "name" : "_id_" }, { "v" : 1, "key" : { "location.geo" : "2d" }, "ns" : "milieu.venues", "name" : "location.geo_" }]

Page 71: Build your first MongoDB App in Ruby @ StrangeLoop 2013

Skon

Page 72: Build your first MongoDB App in Ruby @ StrangeLoop 2013

Sta wh a skon/Users/steve/Code/milieu/app/

▸ config/▸ helpers/▾ model/ mongodb.rb mongoModule.rb user.rb▾ public/ ▸ bootstrap/ ▾ css/ styles.css ▸ images/▾ views/ footer.haml index.haml layout.haml

login.haml navbar.haml register.haml user_dashboard.haml user_profile.haml venue.haml venues.haml app.rb config.ru Gemfile Rakefile README

Page 73: Build your first MongoDB App in Ruby @ StrangeLoop 2013

Download & Install deps⇒ mkdir milieu⇒ cd milieu⇒ wget http://c.spf13.com/dl/GettingStarted.tgz⇒ tar zxvf GettingStarted.tgz⇒ bundle installResolving dependencies...Using bson (1.9.2)Using bson_ext (1.9.2)Using googlestaticmap (1.1.4)Using tilt (1.4.1)Using haml (4.0.3)Using mongo (1.9.2)Using rack (1.5.2)Using rack-protection (1.5.0)Using shotgun (0.9)Using sinatra (1.4.3)Using bundler (1.3.5)Your bundle is complete! Use `bundle show [gemname]` to see where a bundled gem is installed.

Page 74: Build your first MongoDB App in Ruby @ StrangeLoop 2013

Run a⇒ shotgun== Shotgun/WEBrick on http://127.0.0.1:9393/[2013-09-13 21:25:43] INFO WEBrick 1.3.1[2013-09-13 21:25:43] INFO ruby 2.0.0 (2013-06-27) [x86_64-darwin12.3.0][2013-09-13 21:25:43] INFO WEBrick::HTTPServer#start: pid=85344 port=9393

Page 75: Build your first MongoDB App in Ruby @ StrangeLoop 2013

Op Brows to locaost:9393

Page 76: Build your first MongoDB App in Ruby @ StrangeLoop 2013

Pri --- ror Scre

Page 77: Build your first MongoDB App in Ruby @ StrangeLoop 2013

sngVues

Page 78: Build your first MongoDB App in Ruby @ StrangeLoop 2013

Connecng to MongoDB

require 'mongo'require './model/mongoModule'require './model/user'

# Connection code goes hereCONNECTION = Mongo::Connection.new("localhost")DB = CONNECTION.db('milieu')

# Alias to collections goes hereUSERS = DB['users']VENUES = DB['venues']CHECKINS = DB['checkins']

model/mongodb.rb

Page 79: Build your first MongoDB App in Ruby @ StrangeLoop 2013

sng Vues

get '/venues' do # Code to list all venues goes here @venues = VENUES.░░░░░ haml :venuesend

app.rb

Page 80: Build your first MongoDB App in Ruby @ StrangeLoop 2013

sng Vues

get '/venues' do # Code to list all venues goes here @venues = VENUES.find haml :venuesend

app.rb

Page 81: Build your first MongoDB App in Ruby @ StrangeLoop 2013

sng Vues.container .content %h2 Venues %table.table.table-striped %thead %tr %th Name %th Address %th Longitude %th Latitude

%tbody [email protected] do |venue| %tr %td %a{:href => '/venue/' << venue['_id'].to_s}= venue['name'] %td= venue['location']['address'] ? venue['location']['address'] : '&nbsp' %td= venue['location']['geo'][0].round(2) %td= venue['location']['geo'][1].round(2)

views/venues.haml

Page 82: Build your first MongoDB App in Ruby @ StrangeLoop 2013

sng Vueslocalhost:9393/venues

Page 83: Build your first MongoDB App in Ruby @ StrangeLoop 2013

Paginang Vues

get '/venues/?:page?' do @page = params.fetch('page', 1).to_i pp = 10 @venues = VENUES.find.░░░░░(░░░░).░░░░(░░░) @total_pages = (VENUES.░░░░░.to_i / pp).ceil haml :venuesend

app.rb

# replaces the prior entry

Page 84: Build your first MongoDB App in Ruby @ StrangeLoop 2013

Paginang Vues

get '/venues/?:page?' do @page = params.fetch('page', 1).to_i pp = 10 @venues = VENUES.find.skip((@page - 1) * pp).limit(pp) @total_pages = (VENUES.count.to_i / pp).ceil haml :venuesend

app.rb

# replaces the prior entry

Page 85: Build your first MongoDB App in Ruby @ StrangeLoop 2013

.container .content %h2 Venues %table.table.table-striped %thead %tr %th Name %th Address %th Longitude %th Latitude

%tbody [email protected] do |venue| %tr %td %a{:href => '/venue/' << venue['_id'].to_s}= venue['name'] %td= venue['location']['address'] ? venue['location']['address'] : '&nbsp' %td= venue['location']['geo'][0].round(2) %td= venue['location']['geo'][1].round(2)

=pager('/venues')

sng Vuesviews/venues.haml

Page 86: Build your first MongoDB App in Ruby @ StrangeLoop 2013

paging rough Vueslocalhost:9393/venues

Page 87: Build your first MongoDB App in Ruby @ StrangeLoop 2013

Crng

Uss

Page 88: Build your first MongoDB App in Ruby @ StrangeLoop 2013

Crng UssUsers are a bit special in our app

Not just data

Special considerations for secure password handling

Not complicated on MongoDB side, but slightly complicated on Ruby side

Page 89: Build your first MongoDB App in Ruby @ StrangeLoop 2013

Crng Ussclass User

attr_accessor :_id, :name, :email, :email_hash, :salt, :hashed_password, :collection, :updated_at

def init_collection self.collection = 'users' end

def password=(pass) self.salt = random_string(10) unless self.salt self.hashed_password = User.encrypt(pass, self.salt) end

def save col = DB[self.collection] self.updated_at = Time.now col.save(self.to_hash) endend

model/user.rb

Inherited fromMongoModule.rb

Page 90: Build your first MongoDB App in Ruby @ StrangeLoop 2013

Crng Usspost '/register' do u = User.new u.email = params[:email] u.password = params[:password] u.name = params[:name]

if u.save() flash("User created") session[:user] = User.auth( params["email"], params["password"]) redirect '/user/' << session[:user].email.to_s << "/dashboard" else tmp = [] u.errors.each do |e| tmp << (e.join("<br/>")) end flash(tmp) redirect '/create' endend

app.rb

Page 91: Build your first MongoDB App in Ruby @ StrangeLoop 2013

Loing in pa 1configure do enable :sessionsend

before do unless session[:user] == nil @suser = session[:user] endend

get '/user/:email/dashboard' do haml :user_dashboardend

app.rb

Page 92: Build your first MongoDB App in Ruby @ StrangeLoop 2013

Loing in pa 2

post '/login' do if session[:user] = User.auth(params["email"], params["password"]) flash("Login successful") redirect "/user/" << session[:user].email << "/dashboard" else flash("Login failed - Try again") redirect '/login' endend

app.rb

Page 93: Build your first MongoDB App in Ruby @ StrangeLoop 2013

Loing in pa 3

def self.auth(email, pass) u = USERS.find_one("email" => email.downcase) return nil if u.nil? return User.new(u) if User.encrypt( pass, u['salt']) == u['hashed_password'] nil end

user.rb

Page 94: Build your first MongoDB App in Ruby @ StrangeLoop 2013

Us Dashboard.container .content .page-header -unless @suser == nil? %h2="Dashboard" %br %image{src: "http://www.gravatar.com/avatar/" << @suser.email_hash.to_s << '.png'}

%h3= @suser.name.to_s -else redirect '/' %small %a{href: "/user/" << @suser.email.to_s << "/profile"} profile .container#main-topic-nav

views/user_dashboard.haml

Page 95: Build your first MongoDB App in Ruby @ StrangeLoop 2013

Dashboardlocalhost:9393/dashboard

Page 96: Build your first MongoDB App in Ruby @ StrangeLoop 2013

Viing

Uss

Page 97: Build your first MongoDB App in Ruby @ StrangeLoop 2013

nding a us

get '/user/:email/profile' do u = USERS.░░░░░( ░░░░░ => ░░░░░.░░░░░) if u == nil return haml :profile_missing else @user = User.new(u) end haml :user_profileend

app.rb

Page 98: Build your first MongoDB App in Ruby @ StrangeLoop 2013

nding a us

get '/user/:email/profile' do u = USERS.find_one( "email" => params[:email].downcase) if u == nil return haml :profile_missing else @user = User.new(u) end haml :user_profileend

app.rb

Page 99: Build your first MongoDB App in Ruby @ StrangeLoop 2013

Crng an INdex> db.users.ensureIndex({email : 1})

> db.users.getIndexes()[ { "v" : 1, "key" : { "_id" : 1 }, "ns" : "milieu.users", "name" : "_id_" }, { "v" : 1, "key" : { "email" : 1 }, "ns" : "milieu.users", "name" : "email_1" }]

Page 100: Build your first MongoDB App in Ruby @ StrangeLoop 2013

A Vue

Page 101: Build your first MongoDB App in Ruby @ StrangeLoop 2013

Showing a Vue

get '/venue/:_id' do object_id = ░░░░░░░░░░░░░░ @venue = ░░░░░░░░░░( { ░░░░ => object_id }) haml :venueend

app.rb

Page 102: Build your first MongoDB App in Ruby @ StrangeLoop 2013

Showing a Vue

get '/venue/:_id' do object_id = BSON::ObjectId.from_string(params[:_id])

@venue = VENUES.find_one( { :_id => object_id }) haml :venueend

app.rb

Page 103: Build your first MongoDB App in Ruby @ StrangeLoop 2013

Showing a Vue .row .col-md-4 %h2= @venue['name'].to_s %p =@venue['location']['address'].to_s %br= @venue['location']['city'].to_s + ' ' + @venue['location']['state'].to_s + ' ' + @venue['location']['postalCode'].to_s

.col-md-8 %image{:src => '' << gmap_url(@venue, {:height => 300, :width => 450}) }

views/venue.haml

Page 104: Build your first MongoDB App in Ruby @ StrangeLoop 2013

A Vuelocalhost:9393/venue/{id}

Page 105: Build your first MongoDB App in Ruby @ StrangeLoop 2013

Nrby VueS

Page 106: Build your first MongoDB App in Ruby @ StrangeLoop 2013

Nrby Vues

get '/venue/:_id' do object_id = BSON::ObjectId.from_string(params[:_id]) @venue = VENUES.find_one({ :_id => object_id }) @nearby_venues = ░░░░░.░░░░░( {░░░░░ =>{░░░░░=>[ ░░░░░,░░░░░]}} ).░░░░░(4).░░░░░(1) haml :venueend

app.rb

Page 107: Build your first MongoDB App in Ruby @ StrangeLoop 2013

Nrby Vues

get '/venue/:_id' do object_id = BSON::ObjectId.from_string(params[:_id]) @venue = VENUES.find_one({ :_id => object_id }) @nearby_venues = VENUES.find( { :'location.geo' => { ░░░░░ => [ ░░░░░,░░░░░] } }).░░░░░(4).░░░░░(1) haml :venueend

app.rb

Page 108: Build your first MongoDB App in Ruby @ StrangeLoop 2013

Nrby Vues

get '/venue/:_id' do object_id = BSON::ObjectId.from_string(params[:_id]) @venue = VENUES.find_one({ :_id => object_id }) @nearby_venues = VENUES.find( { :'location.geo' => { ░░░░░ => [ ░░░░░,░░░░░] } }).limit(4).skip(1) haml :venueend

app.rb

Page 109: Build your first MongoDB App in Ruby @ StrangeLoop 2013

Nrby Vuesget '/venue/:_id' do object_id = BSON::ObjectId.from_string(params[:_id]) @venue = VENUES.find_one({ :_id => object_id }) @nearby_venues = VENUES.find( { :'location.geo' => { :$near => [ @venue['location']['geo'][0], @venue['location']['geo'][1]] } }).limit(4).skip(1) haml :venueend

app.rb

Page 110: Build your first MongoDB App in Ruby @ StrangeLoop 2013

... .row - @nearby_venues.each do |nearby| .col-md-3 %h2 %a{:href => '/venue/' + nearby['_id'].to_s}= nearby['name'].to_s %p =nearby['location']['address'].to_s %br= nearby['location']['city'].to_s + ' ' + nearby['location']['state'].to_s + ' ' + nearby['location']['postalCode'].to_s

%a{:href => '/venue/' + nearby['_id'].to_s} %image{:src => '' << gmap_url(nearby, {:height => 150, :width => 150, :zoom => 17}) }

views/venue.haml

sng Nrby Vues

Page 111: Build your first MongoDB App in Ruby @ StrangeLoop 2013

Nrby Vueslocalhost:9393/venue/{id}

Page 112: Build your first MongoDB App in Ruby @ StrangeLoop 2013

Checng IN

Page 113: Build your first MongoDB App in Ruby @ StrangeLoop 2013

Checng in

get '/venue/:_id/checkin' do object_id = BSON::ObjectId.from_string(params[:_id]) @venue = VENUES.find_one({ :_id => object_id })

user = USERS. ░░░░░_and_░░░░░(░░░░░) if ░░░░░ ░░░░░ ░░░░░ ░░░░░ ░░░░░ else

░░░░░ ░░░░░ ░░░░░ ░░░░░ end flash('Thanks for checking in') redirect '/venue/' + params[:_id]end

app.rb

Page 114: Build your first MongoDB App in Ruby @ StrangeLoop 2013

Checng inget '/venue/:_id/checkin' do object_id = BSON::ObjectId.from_string(params[:_id]) @venue = VENUES.find_one({ :_id => object_id }) user = USERS.find_and_modify(

:query => ░░░░░, :update => ░░░░░, :new => 1)

if ░░░░░ ░░░░░ ░░░░░ ░░░░░ ░░░░░ else

░░░░░ ░░░░░ ░░░░░ ░░░░░ end flash('Thanks for checking in') redirect '/venue/' + params[:_id]end

app.rb

Page 115: Build your first MongoDB App in Ruby @ StrangeLoop 2013

Checng inget '/venue/:_id/checkin' do object_id = BSON::ObjectId.from_string(params[:_id]) @venue = VENUES.find_one({ :_id => object_id }) user = USERS.find_and_modify( :query => { :_id => @suser._id}, :update => {:$inc =>{ "venues." << object_id.to_s => 1 } }, :new => 1)

if ░░░░░ ░░░░░ ░░░░░ ░░░░░ ░░░░░ else

░░░░░ ░░░░░ ░░░░░ ░░░░░ end flash('Thanks for checking in') redirect '/venue/' + params[:_id]end

app.rb

Page 116: Build your first MongoDB App in Ruby @ StrangeLoop 2013

Checng inget '/venue/:_id/checkin' do object_id = BSON::ObjectId.from_string(params[:_id]) @venue = VENUES.find_one({ :_id => object_id }) user = USERS.find_and_modify(:query => { :_id => @suser._id}, :update => {:$inc => { "venues." << object_id.to_s => 1 } }, :new => 1) if user['venues'][params[:_id]] == 1

VENUES.update(░░░░░) else

VENUES.update(░░░░░) end flash('Thanks for checking in') redirect '/venue/' + params[:_id]end

app.rb

Page 117: Build your first MongoDB App in Ruby @ StrangeLoop 2013

Checng inget '/venue/:_id/checkin' do object_id = BSON::ObjectId.from_string(params[:_id]) @venue = VENUES.find_one({ :_id => object_id }) user = USERS.find_and_modify(:query => { :_id => @suser._id}, :update => {:$inc => { "venues." << object_id.to_s => 1 } }, :new => 1) if user['venues'][params[:_id]] == 1 VENUES.update({ :_id => @venue['_id']}, { :$inc => { :'stats.usersCount' => 1, :'stats.checkinsCount' => 1}}) else VENUES.update({ _id: @venue['_id']}, { :$inc => { :'stats.checkinsCount' => 1}}) end flash('Thanks for checking in') redirect '/venue/' + params[:_id]end

app.rb

Page 118: Build your first MongoDB App in Ruby @ StrangeLoop 2013

You’ve be he def user_times_at if logged_in? times = 'You have checked in here ' if [email protected]? && [email protected][params[:_id]].nil? times << @suser.venues[params[:_id]].to_s else times << '0' end times << ' times' else times = 'Please <a href=\'/login\'>login</a> to join them.' end end

helpers/milieu.rb

Page 119: Build your first MongoDB App in Ruby @ StrangeLoop 2013

Checn In

%p %a.btn.btn-primary.btn-large{:href => '/venue/' + @venue['_id'].to_s + '/checkin'} Check In Here%p =@venue['stats']['usersCount'].ceil.to_s + ' users have checked in here ' + @venue['stats']['checkinsCount'].ceil.to_s + ' times'%p=user_times_at

views/venue.haml

Page 120: Build your first MongoDB App in Ruby @ StrangeLoop 2013

A Vue localhost:9393/venue/{id}

Page 121: Build your first MongoDB App in Ruby @ StrangeLoop 2013

What we’ve led* Model data for

MongoDB

* Use MongoDB tools to import data

* Create records from shell & ruby

* Update records

* Atomic updates

* Create an index

* Create a geo index

* Query for data by matching

* GeoQueries

* Pagination

* Single Document Transactions

* Some ruby, sinatra, haml, etc

Page 122: Build your first MongoDB App in Ruby @ StrangeLoop 2013

Next ?

Page 123: Build your first MongoDB App in Ruby @ StrangeLoop 2013

’s on Ghub

Page 124: Build your first MongoDB App in Ruby @ StrangeLoop 2013

Some Ids* Create interface to add venues

* Connect to foursquare

* Login w/twitter

* Badges or Categories

* Enable searching of venues

* Tips / Reviews

Page 125: Build your first MongoDB App in Ruby @ StrangeLoop 2013

E IF YOU KED !

Questions?

http://spf13.comhttp://github.com/spf13@spf13

Page 126: Build your first MongoDB App in Ruby @ StrangeLoop 2013