-
Notifications
You must be signed in to change notification settings - Fork 24
/
Copy pathREADME.html
258 lines (251 loc) · 25.1 KB
/
README.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
<h1 id="dsphere-geolocation-with-zips">2DSphere Geolocation with Zips</h1>
<p>This example application demonstrates the 2 dimensional geolocation indexed search available within MongoDB.</p>
<h2 id="highlights">Highlights</h2>
<ol style="list-style-type: decimal">
<li><p>A <code>2dsphere</code> index was added to the MongoDB collection index.</p>
<div class="sourceCode"><pre class="sourceCode ruby"><code class="sourceCode ruby"><span class="dt">Zip</span>.collection.indexes.create_one({<span class="st">:loc=</span>><span class="dt">Mongo</span>::<span class="dt">Index</span>::<span class="dt">GEO2DSPHERE</span>})</code></pre></div></li>
<li><p>The index can be removed with the following commanfd</p>
<div class="sourceCode"><pre class="sourceCode ruby"><code class="sourceCode ruby"><span class="dt">Zip</span>.collection.indexes.drop_one(<span class="st">"loc_2dsphere"</span>)</code></pre></div></li>
<li><p>These two commands have been integrated with <code>rake</code>. Don't worry that there is no ActiveRecord involved -- the flow still works and feels natural.</p>
<div class="sourceCode"><pre class="sourceCode ruby"><code class="sourceCode ruby">$ rake db<span class="st">:migrate</span>
== <span class="dv">20151115173006</span> <span class="dt">AddIndexToZips</span>: migrating ===================================
zips_development.createIndexes | <span class="dt">STARTED</span> | {<span class="st">"createIndexes"</span>=><span class="st">"zips"</span>,
<span class="st">"indexes"</span>=>[{<span class="st">:key=</span>>{<span class="st">:loc=</span>><span class="st">"2dsphere"</span>}, <span class="st">:name=</span>><span class="st">"loc_2dsphere"</span>}]}
zips_development.createIndexes | <span class="dt">SUCCEEDED</span> | <span class="fl">0.00048591000000000004</span>s
== <span class="dv">20151115173006</span> <span class="dt">AddIndexToZips</span>: migrated (<span class="fl">0.0077</span>s) ==========================</code></pre></div>
<div class="sourceCode"><pre class="sourceCode ruby"><code class="sourceCode ruby">$ rake db<span class="st">:rollback</span>
== <span class="dv">20151115173006</span> <span class="dt">AddIndexToZips</span>: reverting ===================================
zips_development.dropIndexes | <span class="dt">STARTED</span> | {<span class="st">"dropIndexes"</span>=><span class="st">"zips"</span>, <span class="st">"index"</span>=><span class="st">"loc_2dsphere"</span>}
zips_development.dropIndexes | <span class="dt">SUCCEEDED</span> | <span class="fl">0.000458864</span>s
== <span class="dv">20151115173006</span> <span class="dt">AddIndexToZips</span>: reverted (<span class="fl">0.0070</span>s) ==========================</code></pre></div></li>
<li><p>A new find method was added to the <code>Zip</code> model class which used the <code>$near</code> command to locate other <code>Zip</code> instances within a min/max number of miles. Miles had to be converted to meters.</p>
<div class="sourceCode"><pre class="sourceCode ruby"><code class="sourceCode ruby"><span class="co">#convert miles to meters</span>
miles_to_meters=<span class="fl">1609.34</span>
min_meters=min_miles.to_i*miles_to_meters
max_meters=max_miles.to_i*miles_to_meters
<span class="co">#execute a 2dsphere location find</span>
near_zips=[]
<span class="dv">self</span>.class.collection.find(
<span class="st">:loc=</span>>{<span class="st">:$near=</span>>{
<span class="st">:$geometry=</span>>{<span class="st">:type=</span>><span class="st">"Point"</span>,<span class="st">:coordinates=</span>>[<span class="ot">@longitude</span>,<span class="ot">@latitude</span>]},
<span class="st">:$minDistance=</span>>min_meters,
<span class="st">:$maxDistance=</span>>max_meters}}
).limit(limit).each <span class="kw">do</span> |z|
near_zips << <span class="dt">Zip</span>.new(z)
<span class="kw">end</span></code></pre></div></li>
<li><p>The controller defined a new <code>@locations</code> hash to store a the hash representation of the zip locations. This collection is read in by the <code>index</code> and <code>show</code> pages. Notice that each pin can tell you the city name associate with it.</p>
<div class="sourceCode"><pre class="sourceCode ruby"><code class="sourceCode ruby">[{<span class="st">:lat=</span>><span class="fl">37.228657</span>, <span class="st">:lng=</span>>-<span class="fl">76.542346</span>, <span class="st">:infowindow=</span>><span class="st">"YORKTOWN"</span>},
{<span class="st">:lat=</span>><span class="fl">39.707341</span>, <span class="st">:lng=</span>>-<span class="fl">77.495609</span>, <span class="st">:infowindow=</span>><span class="st">"FORT RITCHIE"</span>},
{<span class="st">:lat=</span>><span class="fl">38.558946</span>, <span class="st">:lng=</span>>-<span class="fl">75.107762</span>, <span class="st">:infowindow=</span>><span class="st">"MILLVILLE"</span>},
{<span class="st">:lat=</span>><span class="fl">39.459959</span>, <span class="st">:lng=</span>>-<span class="fl">77.958915</span>, <span class="st">:infowindow=</span>><span class="st">"MARTINSBURG"</span>},
{<span class="st">:lat=</span>><span class="fl">38.520712</span>,
<span class="st">:lng=</span>>-<span class="fl">76.781677</span>,
<span class="st">:infowindow=</span>><span class="st">"HUGHESVILLE"</span>,
<span class="st">:picture=</span>>{<span class="st">:url=</span>><span class="st">"/images/marker32.png"</span>, <span class="st">:width=</span>><span class="dv">32</span>, <span class="st">:height=</span>><span class="dv">32</span>}}]</code></pre></div></li>
<li><p>The collection of hashes is displayed using the following javascript (and supporting files that were part of GMaps4Rails setup)</p>
<div class="sourceCode"><pre class="sourceCode html"><code class="sourceCode html"><span class="kw"><div</span><span class="ot"> style=</span><span class="st">'width: 800px;'</span><span class="kw">></span>
<span class="kw"><div</span><span class="ot"> id=</span><span class="st">"map"</span><span class="ot"> style=</span><span class="st">'width: 800px; height: 400px;'</span><span class="kw">></div></span>
<span class="kw"></div></span>
<span class="kw"><script</span><span class="ot"> type=</span><span class="st">"text/javascript"</span><span class="kw">></span>
handler <span class="op">=</span> <span class="va">Gmaps</span>.<span class="at">build</span>(<span class="st">'Google'</span>)<span class="op">;</span>
<span class="va">handler</span>.<span class="at">buildMap</span>(<span class="op">{</span> <span class="dt">provider</span><span class="op">:</span> <span class="op">{},</span> <span class="dt">internal</span><span class="op">:</span> <span class="op">{</span><span class="dt">id</span><span class="op">:</span> <span class="st">'map'</span><span class="op">}},</span> <span class="kw">function</span>()<span class="op">{</span>
markers <span class="op">=</span> <span class="va">handler</span>.<span class="at">addMarkers</span>(<span class="op"><%=</span>raw @<span class="va">locations</span>.<span class="at">to_json</span> <span class="op">%></span>)<span class="op">;</span>
<span class="va">handler</span>.<span class="va">bounds</span>.<span class="at">extendWith</span>(markers)<span class="op">;</span>
<span class="va">handler</span>.<span class="at">fitMapToBounds</span>()<span class="op">;</span>
<span class="op">}</span>)<span class="op">;</span>
<span class="op"><</span><span class="ss">/script></span></code></pre></div></li>
</ol>
<h2 id="test-drive">Test Drive</h2>
<ol style="list-style-type: decimal">
<li>Access the root URI. The zipcodes are sorted in alphabetical order so cities in Alaska show up first.</li>
</ol>
<p><a href="./index.png">index page with Alaska</a></p>
<ol start="2" style="list-style-type: decimal">
<li>Add <code>city=BALTIMORE</code> to the URI and show this city. Note the the closest five (5) cities that are within 0 miles of that zip code are displayed.</li>
</ol>
<p><a href="./show-baltimore.png">show page showing closest 5 cities greater than or equal to 0 miles from BALTIMORE</a></p>
<ol start="2" style="list-style-type: decimal">
<li>Add <a href="http://localhost:3000/zips/21214?max_miles=3000&min_miles=50&limit=20">max_miles, min_miles, and limit</a> to locate the nearest N cities that are M miles away from BALTIMORE. This forms a ring around the city.</li>
</ol>
<p><a href="./show-baltimore-3000-50-20.png">show page showing closest 20 cities greater than or equal to 50 miles from BALTIMORE</a></p>
<h2 id="assembly">Assembly</h2>
<p>These are the edits performed to the <code>zips</code> application use to demonstrate integrating the MongoDB Ruby Driver with Rails.</p>
<h3 id="add-the-2dsphere-index">Add the 2dsphere Index</h3>
<ol style="list-style-type: decimal">
<li><p>Add a database migration to house the management of our index. Rails will place a timestamp within the name of this file.</p>
<pre class="shell"><code>$ rails g migration AddIndexToZips
invoke active_record
create db/migrate/20151115173006_add_index_to_zips.rb</code></pre></li>
<li><p>Edit the migration file created in <code>db/migrate</code> with the following <code>up</code> and <code>down</code> commands to add and remove the index. <code>:loc</code> is the field used be the zips collection to hold the geolocation information.</p>
<div class="sourceCode"><pre class="sourceCode ruby"><code class="sourceCode ruby"><span class="kw">class</span> <span class="dt">AddIndexToZips</span> < <span class="dt">ActiveRecord</span>::<span class="dt">Migration</span>
<span class="co"># add a 2dsphere index to Zip.loc field</span>
<span class="kw">def</span> up
<span class="dt">Zip</span>.collection.indexes.create_one({<span class="st">:loc</span> => <span class="dt">Mongo</span>::<span class="dt">Index</span>::<span class="dt">GEO2DSPHERE</span>})
<span class="kw">end</span>
<span class="kw">def</span> down
<span class="dt">Zip</span>.collection.indexes.drop_one(<span class="st">"loc_2dsphere"</span>)
<span class="kw">end</span>
<span class="kw">end</span></code></pre></div></li>
<li><p>Use <code>rake</code> to migrate the database to add the index.</p>
<pre><code>$ rake db:migrate
== 20151115173006 AddIndexToZips: migrating ===================================
D, [2015-11-15T13:05:19.695296 #70768] DEBUG -- : MONGODB | Adding localhost:27017 to the cluster.
D, [2015-11-15T13:05:19.704984 #70768] DEBUG -- : MONGODB | localhost:27017
| zips_development.createIndexes | STARTED |
{"createIndexes"=>"zips", "indexes"=>[{:key=>{:loc=>"2dsphere"}, :name=>"loc_2dsphere"}]}
D, [2015-11-15T13:05:20.018183 #70768] DEBUG -- : MONGODB | localhost:27017
| zips_development.createIndexes | SUCCEEDED | 0.31258843399999997s
== 20151115173006 AddIndexToZips: migrated (0.3304s) ==========================</code></pre></li>
</ol>
<h3 id="updated-gemfile-with-gmaps4rails-gem">Updated Gemfile with Gmaps4Rails Gem</h3>
<p>Add the <code>gmaps4rails</code> gem to the Gemfile. Documentation for the gem is available at <a href="https://github.com/apneadiving/Google-Maps-for-Rails" class="uri">https://github.com/apneadiving/Google-Maps-for-Rails</a>. It is highly recommended that you also watch the referenced <a href="https://www.youtube.com/watch?v=R0l-7en3dUw&feature=youtu.be">YouTube Video</a></p>
<div class="sourceCode"><pre class="sourceCode ruby"><code class="sourceCode ruby">gem <span class="st">'gmaps4rails'</span></code></pre></div>
<pre class="shell"><code>$ bundle
$ rails s</code></pre>
<h3 id="add-attribute-support-for-geolocation-properties-in-zip-model-class">Add Attribute Support for Geolocation Properties in <code>Zip</code> Model Class</h3>
<ol style="list-style-type: decimal">
<li><p>The original <code>zips</code> application left off support for the <code>:loc</code> property. Add <code>:longitude</code> and <code>:latitude</code> as attributes.</p>
<div class="sourceCode"><pre class="sourceCode ruby"><code class="sourceCode ruby"><span class="ot">attr_accessor</span> <span class="st">:id</span>, <span class="st">:city</span>, <span class="st">:state</span>, <span class="st">:population</span>, <span class="st">:longitude</span>, <span class="st">:latitude</span></code></pre></div></li>
<li><p>Add initialization support for the new attributes in the the <code>initialize()</code> method.</p>
<div class="sourceCode"><pre class="sourceCode ruby"><code class="sourceCode ruby"><span class="kw">def</span> initialize(params={})
...
<span class="kw">if</span> params[<span class="st">:loc</span>]
<span class="ot">@longitude</span>=params[<span class="st">:loc</span>][<span class="dv">0</span>]
<span class="ot">@latitude</span>=params[<span class="st">:loc</span>][<span class="dv">1</span>]
<span class="kw">else</span>
<span class="ot">@longitude</span>=params[<span class="st">:longitude</span>]
<span class="ot">@latitude</span>=params[<span class="st">:latitude</span>]
<span class="kw">end</span></code></pre></div></li>
<li><p>Add the new attributes to the query projections within the class. There are at least two occurrences.</p>
<div class="sourceCode"><pre class="sourceCode ruby"><code class="sourceCode ruby">.projection({_id<span class="st">:true</span>, city<span class="st">:true</span>, state<span class="st">:true</span>, pop<span class="st">:true</span>, loc<span class="st">:true</span>})</code></pre></div></li>
</ol>
<h3 id="add-geolocation-search-in-zip-model-class">Add Geolocation Search in <code>Zip</code> Model Class</h3>
<p>Add the following instance method to the <code>Zip</code> model class to perform a 2dsphere, geolocation search for zips near its location. Accept a <code>max_miles</code>, <code>min_miles</code>, and <code>limit</code>. The miles have to be converted to meters. The coordinates are passed in as an array with <code>longitude</code> first and <code>latitude</code> second.</p>
<div class="sourceCode"><pre class="sourceCode ruby"><code class="sourceCode ruby"><span class="co">#return a list of zipcodes within min/max miles</span>
<span class="kw">def</span> near(max_miles, min_miles, limit)
max_miles=max_miles.nil? ? <span class="dv">1000</span> : max_miles.to_i
min_miles=min_miles.nil? ? <span class="dv">0</span> : min_miles.to_i
limit=limit.nil? ? <span class="dv">5</span> : limit.to_i
limit+=<span class="dv">1</span> <span class="kw">if</span> min_miles==<span class="dv">0</span>
<span class="co">#convert miles to meters</span>
miles_to_meters=<span class="fl">1609.34</span>
min_meters=min_miles.to_i*miles_to_meters
max_meters=max_miles.to_i*miles_to_meters
<span class="co">#execute a 2dsphere location find</span>
near_zips=[]
<span class="dv">self</span>.class.collection.find(
<span class="st">:loc=</span>>{<span class="st">:$near=</span>>{
<span class="st">:$geometry=</span>>{<span class="st">:type=</span>><span class="st">"Point"</span>,<span class="st">:coordinates=</span>>[<span class="ot">@longitude</span>,<span class="ot">@latitude</span>]},
<span class="st">:$minDistance=</span>>min_meters,
<span class="st">:$maxDistance=</span>>max_meters}}
).limit(limit).each <span class="kw">do</span> |z|
near_zips << <span class="dt">Zip</span>.new(z)
<span class="kw">end</span>
near_zips
<span class="kw">end</span></code></pre></div>
<h3 id="add-geolocation-search-support-in-zips-controller">Add Geolocation Search Support in <code>Zips</code> Controller</h3>
<ol style="list-style-type: decimal">
<li><p>Add the following helper method to the controller as a private method. It accepts a collection of Zip objects and works with Gmaps3rails to create an array of hashes that is used by googlemaps to display pins in the map. If there is a current <span class="citation">@zip</span> -- it will be made the center of the map with a special icon. Note that this definition is referencing a PNG file placed in the <code>public/images</code> folder.</p>
<div class="sourceCode"><pre class="sourceCode ruby"><code class="sourceCode ruby"><span class="kw">def</span> zip_markers zips
<span class="co">#build the marker for the center of the map</span>
<span class="kw">if</span> <span class="ot">@zip</span>
center_marker = <span class="dt">Gmaps4rails</span>.build_markers(<span class="ot">@zip</span>) <span class="kw">do</span> |zip, marker|
marker.lat zip.latitude
marker.lng zip.longitude
marker.infowindow zip.city
marker.picture(<span class="st">:url=</span>> <span class="st">"/images/marker32.png"</span>,
<span class="st">:width=</span>> <span class="dv">32</span>,
<span class="st">:height=</span>> <span class="dv">32</span>)
<span class="kw">end</span>
<span class="kw">end</span>
<span class="co">#build markers for map</span>
marked_zip=<span class="ot">@zip</span>.nil?
locations = <span class="dt">Gmaps4rails</span>.build_markers(zips) <span class="kw">do</span> |zip, marker|
marker.lat zip.latitude
marker.lng zip.longitude
marker.infowindow zip.city
<span class="co">#add special marker for target city</span>
<span class="kw">if</span> <span class="ot">@zip</span> && zip.id==<span class="ot">@zip</span>.id
marker.picture center_marker[<span class="dv">0</span>][<span class="st">:picture</span>]
marked_zip=<span class="dv">true</span>
<span class="kw">end</span>
<span class="kw">end</span>
<span class="co">#add target city of left out</span>
locations << center_marker[<span class="dv">0</span>] <span class="kw">if</span> !marked_zip
<span class="kw">return</span> locations
<span class="kw">end</span></code></pre></div></li>
<li><p>Add an image file to the <code>public/images</code> folder for the map definition to reference.</p>
<pre class="shell"><code>$ls public/images
marker24.png
marker32.png
marker48.png</code></pre></li>
</ol>
<h3 id="update-actions-to-build-geolocation-markers">Update Actions to Build Geolocation Markers</h3>
<ol style="list-style-type: decimal">
<li><p>Have the index page define a list of geolocation markers for the zipcodes that are deplayed on the page.</p>
<div class="sourceCode"><pre class="sourceCode ruby"><code class="sourceCode ruby"><span class="kw">def</span> index
...
<span class="ot">@zips</span> = <span class="dt">Zip</span>.paginate(args)
<span class="ot">@locations</span> = zip_markers <span class="ot">@zips</span>
<span class="kw">end</span></code></pre></div></li>
<li><p>Have the individual <code>show</code> page display a map with nearby cities.</p>
<div class="sourceCode"><pre class="sourceCode ruby"><code class="sourceCode ruby"><span class="kw">def</span> show
near_zips=<span class="ot">@zip</span>.near(params[<span class="st">:max_miles</span>], params[<span class="st">:min_miles</span>] ,params[<span class="st">:limit</span>])
<span class="ot">@locations</span>=zip_markers near_zips
<span class="kw">end</span></code></pre></div></li>
</ol>
<h3 id="add-map-support-to-views">Add Map Support to Views</h3>
<ol style="list-style-type: decimal">
<li><p>Add the following script file references to the <code>app/views/layouts/application.html.erb</code>. This part of the GMaps4Rails setup.</p>
<div class="sourceCode"><pre class="sourceCode html"><code class="sourceCode html"><span class="kw"><head></span>
...
<span class="kw"><script</span><span class="ot"> src=</span><span class="st">"//maps.google.com/maps/api/js?v=3.23</span><span class="er">&</span><span class="st">sensor=false</span><span class="er">&</span><span class="st">client=</span><span class="er">&</span><span class="st">key=</span><span class="er">&</span><span class="st">libraries=geometry</span><span class="er">&</span><span class="st">language=</span><span class="er">&</span><span class="st">hl=</span><span class="er">&</span><span class="st">region="</span><span class="kw">></script></span>
<span class="kw"><script</span><span class="ot"> src=</span><span class="st">"//cdn.rawgit.com/mahnunchik/markerclustererplus/master/dist/markerclusterer.min.js"</span><span class="kw">></script></span>
<span class="kw"><script</span><span class="ot"> src=</span><span class="st">'//cdn.rawgit.com/printercu/google-maps-utility-library-v3-read-only/master/infobox/src/infobox_packed.js'</span><span class="ot"> type=</span><span class="st">'text/javascript'</span><span class="kw">></script></span>
<span class="kw"></head></span></code></pre></div></li>
<li><p>Add the following to the bottom of the <code>index</code> page (<code>app/views/zips/index.html.erb</code>) and and <code>show</code> page (<code>app/views/zips/show.html.erb</code> except This will display the map and place location markers for elements within the <code>@locations</code> collection`.</p>
<div class="sourceCode"><pre class="sourceCode html"><code class="sourceCode html"><span class="kw"><div</span><span class="ot"> style=</span><span class="st">'width: 800px;'</span><span class="kw">></span>
<span class="kw"><div</span><span class="ot"> id=</span><span class="st">"map"</span><span class="ot"> style=</span><span class="st">'width: 800px; height: 400px;'</span><span class="kw">></div></span>
<span class="kw"></div></span>
<span class="kw"><script</span><span class="ot"> type=</span><span class="st">"text/javascript"</span><span class="kw">></span>
handler <span class="op">=</span> <span class="va">Gmaps</span>.<span class="at">build</span>(<span class="st">'Google'</span>)<span class="op">;</span>
<span class="va">handler</span>.<span class="at">buildMap</span>(<span class="op">{</span> <span class="dt">provider</span><span class="op">:</span> <span class="op">{},</span> <span class="dt">internal</span><span class="op">:</span> <span class="op">{</span><span class="dt">id</span><span class="op">:</span> <span class="st">'map'</span><span class="op">}},</span> <span class="kw">function</span>()<span class="op">{</span>
markers <span class="op">=</span> <span class="va">handler</span>.<span class="at">addMarkers</span>(<span class="op"><%=</span>raw @<span class="va">locations</span>.<span class="at">to_json</span> <span class="op">%></span>)<span class="op">;</span>
<span class="va">handler</span>.<span class="va">bounds</span>.<span class="at">extendWith</span>(markers)<span class="op">;</span>
<span class="va">handler</span>.<span class="at">fitMapToBounds</span>()<span class="op">;</span>
<span class="op">}</span>)<span class="op">;</span>
<span class="op"><</span><span class="ss">/script></span></code></pre></div></li>
</ol>
<h2 id="heroku-deployment">Heroku Deployment</h2>
<p>This deployment assumes that you have already deployed the <code>Zips</code> application and can re-use the same database for both applications.</p>
<ol style="list-style-type: decimal">
<li><p>Register your application with Heroku by changing to the directory with a git repository and invoking <code>heroku apps:create (appname)</code>.</p>
<p><strong>Note that your application must be in the root directory of the development folder hosting the git repository.</strong></p>
<pre><code>$ cd fullstack-course3-module2-geozips
$ heroku apps:create appname
Creating appname... done, stack is cedar-14
https://appname.herokuapp.com/ | https://git.heroku.com/appname.git
Git remote heroku added</code></pre>
<p>This will add an additional remote to your git repository.</p>
<pre class="shell"><code>$ git remote --verbose
heroku https://git.heroku.com/appname.git (fetch)
heroku https://git.heroku.com/appname.git (push)
...</code></pre></li>
<li><p>Add a <code>MONGOLAB_URI</code> environment variable from the <code>zips</code> application deployment. <code>dbhost</code> is both host and port# concatenated together, separated by a ":" (host:port) in this example.</p>
<pre class="shell"><code>$ cd fullstack-course3-module1-zips
$ heroku config | grep MONGOLAB_URI
$ cd fullstack-course3-module2-geozips
$ heroku config:add MONGOLAB_URI=mongodb://dbuser:dbpass@dbhost/dbname</code></pre></li>
<li><p>Deploy application</p>
<pre class="shell"><code>$ git push heroku master</code></pre></li>
<li><p>Create the geolocation index. This has been packaged as a ActiveRecord database migration task. So use <code>heroku run rake db:migrate</code> to put in place.</p>
<pre class="shell"><code>$ heroku run rake db:migrate
Running `rake db:migrate` attached to terminal... up, run.4636
...
DEBUG | {"createIndexes"=>"zips", "indexes"=>[{:key=>{:loc=>"2dsphere"}, :name=>"loc_2dsphere"}]}</code></pre></li>
</ol>
<h2 id="access-application">Access Application</h2>
<ol style="list-style-type: decimal">
<li><p>Access URL</p>
<pre class="url"><code>http://appname.herokuapp.com/zips/21044?min_miles=5&limit=20</code></pre></li>
</ol>