Ruby on Rails
रेलमपेल का उपयोग रेल के साथ
खोज…
लेआउट हेडर में गूगल मैप्स जावास्क्रिप्ट टैग जोड़ें
टर्बोलिंक्स के साथ गूगल मैप्स को ठीक से काम करने के लिए, जावास्क्रिप्टस्क्रिप्ट को सीधे लेआउट हेडर में जोड़ें, बजाय इसे एक दृश्य में शामिल करने के।
# app/views/layouts/my_layout.html.haml
!!!
%html{:lang => 'en'}
%head
- # ...
= google_maps_api_script_tag
google_maps_api_script_tag
सर्वश्रेष्ठ सहायक में परिभाषित किया गया है।
# app/helpers/google_maps_helper.rb
module GoogleMapsHelper
def google_maps_api_script_tag
javascript_include_tag google_maps_api_source
end
def google_maps_api_source
"https://maps.googleapis.com/maps/api/js?key=#{google_maps_api_key}"
end
def google_maps_api_key
Rails.application.secrets.google_maps_api_key
end
end
आप अपने एप्लिकेशन को Google के साथ पंजीकृत कर सकते हैं और Google एपीआई कंसोल में अपनी एपीआई कुंजी प्राप्त कर सकते हैं। Google के पास एक छोटा गाइड है कि कैसे गूगल मैप्स जावास्क्रिप्ट एपी के लिए एक एपीआई कुंजी का अनुरोध करें ।
एपीआई कुंजी को secrets.yml
फ़ाइल में संग्रहीत किया जाता है:
# config/secrets.yml
development:
google_maps_api_key: '...'
# ...
production:
google_maps_api_key: '...'
# ...
जोड़ने के लिए मत भूलना config/secrets.yml
अपने को .gitignore
फ़ाइल और makre सुनिश्चित करें कि आप रिपोजिटरी को api कुंजी के लिए प्रतिबद्ध नहीं है।
मॉडल को जियोकोड
मान लीजिए, आपके उपयोगकर्ताओं और / या समूहों में प्रोफ़ाइल हैं और आप एक Google मानचित्र पर पता प्रोफ़ाइल फ़ील्ड प्रदर्शित करना चाहते हैं।
# app/models/profile_fields/address.rb
class ProfileFields::Address < ProfileFields::Base
# Attributes:
# label, e.g. "Work address"
# value, e.g. "Willy-Brandt-Straße 1\n10557 Berlin"
end
पतों को जियोडोड करने का एक शानदार तरीका है, यानी longitude
प्रदान करें और latitude
जियोकोडर रत्न है ।
अपने Gemfile
जियोकोडर जोड़ें और इसे स्थापित करने के लिए bundle
चलाएं।
# Gemfile
gem 'geocoder', '~> 1.3'
डेटाबेस में स्थान बचाने के लिए latitude
और longitude
लिए डेटाबेस कॉलम जोड़ें। हर बार जब भी आपको स्थान की आवश्यकता होती है, तो जियोकोडिंग सेवा को क्वेरी करने की तुलना में यह अधिक कुशल है। यह तेज़ है और आप इतनी जल्दी क्वेरी सीमा नहीं मार रहे हैं।
➜ bin/rails generate migration add_latitude_and_longitude_to_profile_fields \
latitude:float longitude:float
➜ bin/rails db:migrate # Rails 5, or:
➜ rake db:migrate # Rails 3, 4
अपने मॉडल में जियोकोडिंग तंत्र जोड़ें। इस उदाहरण में, पता स्ट्रिंग को value
विशेषता में संग्रहीत किया जाता है। जब रिकॉर्ड बदल गया है, तो प्रदर्शन करने के लिए जियोकोडिंग को कॉन्फ़िगर करें, और केवल whan एक मान मौजूद है:
# app/models/profile_fields/address.rb
class ProfileFields::Address < ProfileFields::Base
geocoded_by :value
after_validation :geocode, if: ->(address_field){
address_field.value.present? and address_field.value_changed?
}
end
डिफ़ॉल्ट रूप से, जियोकोड, लुकअप सेवा के रूप में Google का उपयोग करता है। इसमें दूरी की गणना या निकटता खोज जैसी कई दिलचस्प विशेषताएं हैं। अधिक जानकारी के लिए, जियोकोड README पर एक नज़र डालें।
प्रोफ़ाइल दृश्य में एक Google मानचित्र पर पते दिखाएं
प्रोफ़ाइल दृश्य पर, किसी उपयोगकर्ता या समूह के प्रोफ़ाइल फ़ील्ड को किसी सूची में और साथ ही Google मानचित्र पर पता फ़ील्ड दिखाएं।
- # app/views/profiles/show.html.haml
%h1 Contact Information
.profile_fields
= render @profile_fields
.google_map{data: address_fields: @address_fields.to_json }
नियंत्रक में उपयुक्त @profile_fields
और @address_fields
सेट किए गए हैं:
# app/controllers/profiles_controller.rb
class ProfilesController < ApplicationController
def show
# ...
@profile_fields = @user_or_group.profile_fields
@address_fields = @profile_fields.where(type: 'ProfileFields::Address')
end
end
मानचित्र को प्रारंभ करें, मार्करों को रखें, ज़ूम और अन्य मानचित्र सेटिंग्स को जावास्क्रिप्ट के साथ सेट करें।
जावास्क्रिप्ट के साथ मानचित्र पर मार्कर सेट करें
मान लीजिए, एक .google_map
div है, जो मानचित्र बन जाएगा, और जिसके पास पता फ़ील्ड हैं जो data
विशेषता के रूप में मार्कर के रूप में दिखाते हैं।
उदाहरण के लिए:
<!-- http://localhost:3000/profiles/123 -->
<div class="google_map" data-address-fields="[
{label: 'Work address', value: 'Willy-Brandt-Straße 1\n10557 Berlin',
position: {lng: ..., lat: ...}},
...
]"></div>
$(document).ready
का उपयोग करने के लिए। पहले से ही टर्बोलिंक के साथ घटना को हाथ से टर्बोलिंक घटनाओं के प्रबंधन के बिना, jquery.turbolinks मणि का उपयोग करें।
यदि आप मानचित्र के साथ कुछ अन्य संचालन करना चाहते हैं, तो बाद में, उदाहरण के लिए फ़िल्टरिंग या जानकारी विंडो, यह कॉफी स्क्रिप्ट वर्ग द्वारा प्रबंधित मानचित्र के लिए सुविधाजनक है।
# app/assets/javascripts/google_maps.js.coffee
window.App = {} unless App?
class App.GoogleMap
constructor: (map_div)->
# TODO: initialize the map
# TODO: set the markers
कई कॉफी स्क्रिप्ट फ़ाइलों का उपयोग करते समय, जो डिफ़ॉल्ट रूप से नामांकित होते हैं, यह एक वैश्विक App
नाम स्थान को परिभाषित करने के लिए सुविधाजनक है, जो सभी कॉफी स्क्रिप्ट फ़ाइलों द्वारा साझा किया जाता है।
फिर, (संभवतः कई) .google_map
माध्यम से लूप करें और उनमें से प्रत्येक के लिए App.GoogleMap
वर्ग का एक उदाहरण बनाएं।
# app/assets/javascripts/google_maps.js.coffee
# ...
$(document).ready ->
App.google_maps = []
$('.google_map').each ->
map_div = $(this)
map = new App.GoogleMap map_div
App.google_maps.push map
कॉफी स्क्रिप्ट क्लास का उपयोग करके मानचित्र को आरम्भ करें।
एक App.GoogleMap
कॉफी स्क्रिप्ट वर्ग प्रदान किया गया है , Google मानचित्र को इस तरह से आरंभ किया जा सकता है:
# app/assets/javascripts/google_maps.js.coffee
# ...
class App.GoogleMap
map_div: {}
map: {}
constructor: (map_div)->
@map_div = map_div
@init_map()
@reference_the_map_as_data_attribute
# To access the GoogleMap object or the map object itself
# later via the DOM, for example
#
# $('.google_map').data('GoogleMap')
#
# store references as data attribute of the map_div.
#
reference_the_map_as_data_attribute: ->
@map_div.data 'GoogleMap', this
@map_div.data 'map', @map
init_map: ->
@map = new google.maps.Map(@dom_element, @map_configuration) if google?
# `@map_div` is the jquery object. But google maps needs
# the real DOM element.
#
dom_element: ->
@map_div.get(0)
map_configuration: -> {
scrollWheel: true
}
संभावित map_configuration
विकल्पों के बारे में अधिक जानने के लिए, Google के MapOptions दस्तावेज़ और नियंत्रण तत्वों को जोड़ने के लिए उनके गाइड पर एक नज़र डालें।
संदर्भ के लिए, वर्ग google.maps.Map
यहाँ बड़े पैमाने पर प्रलेखित है ।
कॉफी स्क्रिप्ट क्लास का उपयोग करके मानचित्र मार्करों को प्रारंभ करें
समय प्रदान किए गए App.GoogleMap
कॉफी स्क्रिप्ट वर्ग और मार्कर जानकारी में संग्रहीत किया जा रहा data-address-fields
की विशेषता .google_map
div, मानचित्र मार्कर इस तरह के नक्शे पर प्रारंभ किया जा सकता है:
# app/assets/javascripts/google_maps.js.coffee
# ...
class App.GoogleMap
# ...
markers: []
constructor: (map_div)->
# ...
@init_markers()
address_fields: ->
@map_div.data('address-fields')
init_markers: ->
self = this # to reference the instance as `self` when `this` is redefined.
self.markers = []
for address_field in self.address_fields()
marker = new google.maps.Marker {
map: self.map,
position: {
lng: address_field.longitude,
lat: address_field.latitude
},
# # or, if `position` is defined in `ProfileFields::Address#as_json`:
# position: address_field.position,
title: address_field.value
}
self.markers.push marker
मार्कर विकल्पों के बारे में अधिक जानने के लिए, Google के MarkerOptions प्रलेखन और मार्करों को उनके गाइड पर एक नज़र डालें।
कॉफी स्क्रिप्ट क्लास का उपयोग करके मैप को ऑटो-जूम करें
एक प्रदान की App.GoogleMap
कॉफी स्क्रिप्ट वर्ग के साथ google.maps.Map
के रूप में जमा @map
और google.maps.Marker
रों के रूप में जमा @markers
, नक्शे ऑटो जूम, यानी समायोजित कि सभी मार्करों दिखाई दे रहे हैं, इस तरह हो सकता है : इस तरह से नक्शे पर:
# app/assets/javascripts/google_maps.js.coffee
# ...
class App.GoogleMap
# ...
bounds: {}
constructor: (map_div)->
# ...
@auto_zoom()
auto_zoom: ->
@init_bounds()
# TODO: Maybe, adjust the zoom to have a maximum or
# minimum zoom level, here.
init_bounds: ->
@bounds = new google.maps.LatLngBounds()
for marker in @markers
@bounds.extend marker.position
@map.fitBounds @bounds
सीमा के बारे में अधिक जानने के लिए, Google के LatLngBounds प्रलेखन पर एक नज़र डालें।
मॉडल के गुणों को json के रूप में उजागर करना
एक Google मानचित्र पर मार्कर के रूप में पता प्रोफ़ाइल फ़ील्ड प्रदर्शित करने के लिए, पता फ़ील्ड ऑब्जेक्ट्स को जावास्क्रिप्ट ऑब्जेक्ट्स के रूप में जावास्क्रिप्ट में पारित करना होगा।
नियमित डेटाबेस विशेषताएँ
जब एक ApplicationRecord
ऑब्जेक्ट पर to_json
को कॉल किया जाता है, तो डेटाबेस विशेषताएँ स्वचालित रूप से उजागर हो जाती हैं।
एक को देखते हुए ProfileFields::Address
के साथ मॉडल label
, value
, longitude
और latitude
गुण, address_field.as_json
एक में परिणाम Hash
, जैसे प्रतिनिधित्व,
address_field.as_json # =>
{label: "Work address", value: "Willy-Brandt-Straße 1\n10557 Berlin",
longitude: ..., latitude: ...}
जो कि json string to_json
में परिवर्तित हो जाता है:
address_field.to_json # =>
"{\"label\":\"Work address\",\"value\":\"Willy-Brandt-Straße 1\\n
10557 Berlin\",\"longitude\":...,\"latitude\":...}"
यह उपयोगी है क्योंकि यह जावास्क्रिप्ट और बाद में जावास्क्रिप्ट में label
और value
का उपयोग करने की अनुमति देता है, उदाहरण के लिए मानचित्र मार्करों के लिए टूल टिप्स दिखाने के लिए।
अन्य विशेषताएँ
अन्य वर्चुअल विशेषताओं को as_json
विधि को ओवरराइड करके उजागर किया जा सकता है।
उदाहरण के लिए, title
विशेषता को उजागर करने के लिए, इसे मर्ज as_json
गए as_json
हैश में शामिल करें:
# app/models/profile_fields/address.rb
class ProfileFields::Address < ProfileFields::Base
# ...
# For example: "John Doe, Work address"
def title
"#{self.parent.name}, #{self.label}"
end
def as_json
super.merge {
title: self.title
}
end
end
उपरोक्त उदाहरण मूल as_json
पद्धति को कॉल करने के लिए super
का उपयोग करता है, जो ऑब्जेक्ट की मूल विशेषता हैश लौटाता है, और आवश्यक स्थिति हैश के साथ विलय करता है।
as_json
और to_json
बीच के अंतर को समझने के लिए, to_json
इस ब्लॉग पोस्ट पर एक नज़र डालें ।
स्थान
मार्करों को रेंडर करने के लिए, गूगल मैप्स एपीआई, डिफ़ॉल्ट रूप से, एक position
हैश की आवश्यकता होती है, जिसमें देशांतर और अक्षांश को क्रमशः lng
और lat
रूप में संग्रहीत किया जाता है।
यह स्थिति हैश को जावास्क्रिप्ट में बनाई जा सकती है, बाद में, या यहाँ जब पते के क्षेत्र के जौन प्रतिनिधित्व को परिभाषित करते हुए:
पते के क्षेत्र के json विशेषता के रूप में इस position
को प्रदान करने के लिए, बस मॉडल पर as_json
विधि को ओवरराइड करें।
# app/models/profile_fields/address.rb
class ProfileFields::Address < ProfileFields::Base
# ...
def as_json
super.merge {
# ...
position: {
lng: self.longitude,
lat: self.latitude
}
}
end
end