
Rubystas! Lo prometido aquí está. La segunda parte del tutorial del StreetMusicMap. Si quieres revisar la parte 1 de la historia, en donde explico como crear una relación uno a muchos uniendo 2 scaffolds «Musician» e «Instrument» te dejó por aquí el artículo.
En la segunda parte, vamos a integrar esa data que guardamos a traves del scaffold creado, para visualizarla de una forma entretenida e interactiva usando la gema gmaps4Rails.
Te sugiero que vayas por una buena taza de café antes de comenzar.
Instalando la gema geocoder.
Vamos a agregar la gema geocoder en mapa/Gemfile:
gem 'geocoder'
Luego en el terminal:
$ bundle
y reiniciamos el server con:
$ rails s
Geolocalizando a partir del campo «address».
Abres app/models/Musician.rb y agregas esta línea:
class Musician < ActiveRecord::Base belongs_to :instrument geocoded_by :address after_validation :geocode end
En http://locahost:3000/musicians/new agregraremos 2 nuevos registros, dejamos vacíos los campos «latitude» y «longitude» . Luego te darás cuenta que al presionar «create musician» automáticamente se agregan valores. «Santiago Chile» en el campo address, obtendremos «-33.4367933» en latitude y «–70.64107299999» en longitude.
Geocoder es responsable de devolver las coordenadas como «Response» a partir de nuestra «Request» solicitada…Interesante..cierto?
pd: si no sabes por qué aparece este belongs_to:instruments quizás necesitas revisar la parte 1 del tutorial en donde explico todo eso)
Instalando la gema Gmaps4rails.
Vamos a agregar la gema gmaps4rails en mapa/Gemfile:
gem 'gmaps4rails'
Luego en el terminal:
$ bundle
y reiniciamos el server con:
$ rails s
Agregando algunas referencias .js en la vista parcial application.html.erb.
Abrimos el archivo app/views/application.html.erb y agregamos el js de bootstrap, googlemap api y markerclustered ántes de </head>
<!-- bootstrap 3--> <script src="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script> <!-- google maps --> <script type="text/javascript" src="//maps.googleapis.com/maps/api/js?v=3.13&sensor=false&libraries=geometrykey=AIzaSyBX2Veo_ENuSNEXA3fdZS54WAOA9_wrm-Y"> </script> <!-- markerClustered --> <script src='//google-maps-utility-library-v3.googlecode.com/svn/tags/markerclustererplus/2.0.14/src/markerclusterer_packed.js' type='text/javascript'></script>
Agregando el div «Map» en fullScreen con Bootstrap.
Para dibujar el mapa en modo fullscreen (en cualquier dispositivo) me basé en este ejemplo disponible en Bootstrap examples.
No fue exactamente un copyPaste del ejemplo…tuve que modificar un poquito siguiendo estos pasos para adaptarlo a nuestro propósito.
Primero, agrega una referencia minificada de bootstrap.min.css antes de todas las referencias .js que incluimos en app/views/application.html.erb
<!-- Latest compiled and minified CSS --> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css">
Segundo, descargas el archivo cover.css y lo guardas en app/assets/stylesheets/cover.css
Tercero, buscas la linea en cover.css :
@media (min-width: 992px) { .masthead, .mastfoot, .cover-container { width: 700px; } }
y la reemplazas por esta otra:
@media (min-width: 992px) { .masthead, .mastfoot, .cover-container { width: 100%; } }
Tercero, abres app/views/musicians/index.html.erb y dibujamos el <div id=»map»> que cargará el contenido de nuestro google map tal como la imagen
<!-- contenedor del mapa --> <div class="site-wrapper"> <div id="map" class="site-wrapper-inner"> <div class="cover-container"> </div> </div> </div> <!--//fin contenedor mapa--> <!-- footer --> <div class="container-fluid"> <div class="row"> <div class=" col-lg-12 mastfoot"> <div class="inner"> <p>street music map <%= link_to 'New Musician', new_musician_path %> </p> </div> </div> </div> </div> <!-- //fin footer-->
Musician Controller: Cargando los datos en el objeto @Hash.
En el controller musician en app/controllers/musicians_controller.rb cargamos un objeto @hash y llamamos al método buid_markers() de la gema Gmaps4Rails. Este método necesita un objeto en este caso lo cargamos con @musicians, el cual se comunica con el modelo a través de Musician.All devolviendo todos los registros de musicos que cargamos previamente.
Luego creamos el Marcador, damos su latitud, longitud y configuramos una ventana de información que se verá así.
def index @musicians = Musician.all @hash = Gmaps4rails.build_markers(@musicians) do |musician, marker| marker.lat musician.latitude marker.lng musician.longitude marker.infowindow "<div class='box' style='width:200px;'><h4><strong>"+musician.musician_name+", "+musician.instrument.instrument_name+"</strong></h4><img src='http://img.youtube.com/vi/"+musician.youtube_video+"/mqdefault.jpg' width='111' height='90' class=''></div>" end end
Agregando el Script que dibuja el Mapa.
Ahora, inmediatamente después del html, vamos a añadir al final de app/views/musicians/index.html.erb este script:
<script type="text/javascript"> handler = Gmaps.build('Google'); handler.buildMap({ provider: {}, internal: {id: 'map'}}, function(){ markers = handler.addMarkers(<%=raw @hash.to_json %>); handler.bounds.extendWith(markers); handler.fitMapToBounds(); }); </script>
Lo que hace básicamente este script es construir el google Map.
Toda la data está contenida en el objeto @hash y google map con su método .addMarkers nos pide cargar un objeto «parseado a Json«. Para lograr esto en ruby lo hacemos asi <%=raw @hash.to_json %>
Google Maps trabaja con JSON, un standard para el intercambio de datos, con el fin de no atar su tecnología a un lenguaje de programación específico, sino que todo lo contrario, hacer que su tecnología sea compatible con cualquier lenguaje de programación con el que quieras trabajar.
Haz la prueba de imprimir por pantalla este código de ruby en la vista index:
<%=raw @hash.to_json %>
Puedes notar que obtienes una cadena de texto entre varios corchetes [{…},{…}] cierto? bueno, es la misma data que ingresamos en musician/new pero parseada en formato JSON, y si copias esta cadena más abajo en un json-parser como el que encontré, te mostrará la cadena en versión «bonita» y más legible.
[{"lat":49.2827291,"lng":-123.1207375,"infowindow":"\u003cdiv class='box' style='width:200px;'\u003e\u003ch4\u003e\u003cstrong\u003eAndres, guitarra\u003c/strong\u003e\u003c/h4\u003e\u003cimg src='http://img.youtube.com/vi/ANj8IJs38qU/mqdefault.jpg' width='111' height='90' class=''\u003e\u003c/div\u003e"},{"lat":-37.814107,"lng":144.96328,"infowindow":"\u003cdiv class='box' style='width:200px;'\u003e\u003ch4\u003e\u003cstrong\u003eEnsamble de Bronces Huevos Fritos, Brass\u003c/strong\u003e\u003c/h4\u003e\u003cimg src='http://img.youtube.com/vi/9WA-W7lI820/mqdefault.jpg' width='111' height='90' class=''\u003e\u003c/div\u003e"},{"lat":-33.4367933,"lng":-70.64107299999999,"infowindow":"\u003cdiv class='box' style='width:200px;'\u003e\u003ch4\u003e\u003cstrong\u003eAndres, piano\u003c/strong\u003e\u003c/h4\u003e\u003cimg src='http://img.youtube.com/vi/ANj8IJs38qU/mqdefault.jpg' width='111' height='90' class=''\u003e\u003c/div\u003e"},{"lat":-33.4691199,"lng":-70.641997,"infowindow":"\u003cdiv class='box' style='width:200px;'\u003e\u003ch4\u003e\u003cstrong\u003eAndrés, guitarra\u003c/strong\u003e\u003c/h4\u003e\u003cimg src='http://img.youtube.com/vi/ANj8IJs38qU/mqdefault.jpg' width='111' height='90' class=''\u003e\u003c/div\u003e"},{"lat":-33.4367933,"lng":-70.64107299999999,"infowindow":"\u003cdiv class='box' style='width:200px;'\u003e\u003ch4\u003e\u003cstrong\u003eAndrés, didgeridoo\u003c/strong\u003e\u003c/h4\u003e\u003cimg src='http://img.youtube.com/vi//mqdefault.jpg' width='111' height='90' class=''\u003e\u003c/div\u003e"},{"lat":-33.4363397,"lng":-70.6435372,"infowindow":"\u003cdiv class='box' style='width:200px;'\u003e\u003ch4\u003e\u003cstrong\u003efunky, didgeridoo\u003c/strong\u003e\u003c/h4\u003e\u003cimg src='http://img.youtube.com/vi/lMpZGAUGk8w/mqdefault.jpg' width='111' height='90' class=''\u003e\u003c/div\u003e"}]
Con estos pasos doy por finalizado el tutorial, si quieres agregar un Buscador de Músicos o de Instrumentos, revisa este Tutorial creado por Gonzalo «Haciendo un pequeño buscador en Ruby on Rails». También para más personalizaciones del infoWindow que aparece en el, puedes revisar los ejemplos de gmaps4rails o descargar el código fuente del tutorial desde el repo que comparto con ustedes en mi cuenta de Github.
Hay bastante más que podríamos seguir integrando pero hasta aquí es la base del «how to» de este prototipo streetmusicmap y es totalmente reusable con otros conceptos. Lo entretenido es saber que en un rato (bueno o un fin de semana) puedes lograr con Ruby on Rails y unas cuantas gemas útiles, prototipos que concretan todas esas locas buenas ideas 🙂

- Friendly URL en Rails - marzo 8, 2015
- Borrar un Scaffold en Ruby on Rails - enero 24, 2015
- «My Concerts Wishlist» ajax scaffold Ruby on Rails - enero 1, 2015
- StreetmusicMap parte 2: Integración Gmaps4Rails - diciembre 12, 2014
- StreetmusicMap parte 1: Combobox uno a muchos en Ruby on Rails - diciembre 11, 2014
- Twitter Search API + Ruby on Rails (II parte) - septiembre 24, 2014
- Twitter Search API + Ruby on Rails - septiembre 24, 2014
- SSL error: Certificate Verify Failed - septiembre 18, 2014
Deja un comentario