简体   繁体   English

Rails 5,Gmaps4Rails-设置

[英]Rails 5, Gmaps4Rails - setup

I have been trying for years to figure out how to incorporate gmaps4rails in a rails app. 多年来,我一直在尝试找出如何将gmaps4rails集成到Rails应用程序中。

I have made an entirely new app and tried fresh. 我做了一个全新的应用程序,并尝试了新鲜。

I can't figure out what's going wrong. 我不知道怎么了。 I'm looking for setup instructions that are complete and up to date. 我正在寻找完整且最新的安装说明。 Many SO posts refer to old versions of dependencies that end up saying that the issue is solved in a later version. 许多SO帖子都提到了旧版本的依赖关系,最终说该问题在更高版本中得到了解决。

Currently, I have this in my view: 目前,我认为:

<script src="//maps.google.com/maps/api/js?v=3.23&key=<%= ENV['GOOGLE_MAPS_API_KEY'] %>"></script>
<script src="//google-maps-utility-library-v3.googlecode.com/svn/tags/markerclustererplus/2.0.14/src/markerclusterer_packed.js" type="text/javascript"></script>

<div style='width: 800px;'>
  <div id="map" style='width: 800px; height: 400px;'></div>
</div>

<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>

In my application.js, I have: 在我的application.js中,我有:

//= require jquery
//= require jquery_ujs
//= require turbolinks
//= require bootstrap-sprockets
//= require moment
//= require bootstrap-datetimepicker
//= require pickers
//= require underscore
//= require gmaps/google
//= require markerclusterer
//= require_tree .

I have saved the production version of underscore.js in my vendor/assets/javascripts folder. 我已经将underscore.js的生产版本保存在我的vendor / assets / javascripts文件夹中。 I also saved markerclusterer.js as a file in the same folder. 我也将markerclusterer.js保存为同一文件夹中的文件。

In my gem file, I have: 在我的gem文件中,我有:

gem 'geocoder'
gem 'gmaps4rails', '~> 2.1', '>= 2.1.2'
gem 'countries'
gem 'country_select'

In my controller, I have: 在我的控制器中,我有:

class AddressesController < ApplicationController

    def index
    end

    def show
        @hash = Gmaps4rails.build_markers(@address) do |address, marker|
          marker.lat address.latitude
          marker.lng address.longitude
       end
    end

    def new
        @address = Address.new
    end 

    def create
    @address = Address.new(address_params)
    # authorize @address

    respond_to do |format|
      if @address.save
        format.html { redirect_to @address, notice: 'Address was successfully created.' }
        format.json { render :show, status: :created, location: @address }
      else
        format.html { render :new }
        format.json { render json: @address.errors, status: :unprocessable_entity }
      end
    end
  end


  private
    # Use callbacks to share common setup or constraints between actions.
    def set_address
      @address = Address.find(params[:id])
      # authorize @address
    end

    # Never trust parameters from the scary internet, only allow the white list through.
    def address_params
      params[:address].permit(:unit, :building, :street_number, :street, :city, :region, :zip, :country, :time_zone, :latitude, :longitude)
    end


    def user_time_zone(&block)
      Time.use_zone(current_user.time_zone, &block)
    end
end

When I try to render the view with the map, the chrome inspector shows errors as: 当我尝试使用地图渲染视图时,Chrome检查器将错误显示为:

v3.googlecode.com/svn/tags/markerclustererplus/2.0.14/src/markerclusterer_packed.js Failed to load resource: the server responded with a status of 404 (Not Found) chrome-extension://mkjojgglmmcghgaiknnpgjgldgaocjfd/content/contentScripts/kwift.CHROME.min.js:1271 Uncaught SyntaxError: Identifier 'findGoodContent' has already been declared util.js:221 Google Maps API warning: NoApiKeys https://developers.google.com/maps/documentation/javascript/error-messages#no-api-keys util.js:221 Google Maps API warning: RetiredVersion https://developers.google.com/maps/documentation/javascript/error-messages#retired-version util.js:221 Google Maps API warning: InvalidKey https://developers.google.com/maps/documentation/javascript/error-messages#invalid-key v3.googlecode.com/svn/tags/markerclustererplus/2.0.14/src/markerclusterer_packed.js加载资源失败:服务器响应状态为404(未找到)chrome-extension:// mkjojgglmmcghgaiknnpgjgldgaocjfd / content / contentScripts / kwift.CHROME.min.js:1271未捕获的SyntaxError:标识符'findGoodContent'已被声明为util.js:221 Google Maps API警告:NoApiKeys https://developers.google.com/maps/documentation/javascript/error-messages #no-api-keys util.js:221 Google Maps API警告:RetiredVersion https://developers.google.com/maps/documentation/javascript/error-messages#retired-version util.js:221 Google Maps API警告: InvalidKey https://developers.google.com/maps/documentation/javascript/error-messages#invalid-key

I don't understand any of these errors and I can't find instructions for how to setup this gem to use it in rails. 我不了解任何这些错误,也找不到如何设置此gem使其在rails中使用的说明。 I can see that it has been downloaded a lot - people must have figured out how to set it up. 我可以看到它已经下载了很多-人们一定已经弄清楚如何设置它。 I am sending myself crazy trying to figure this out. 我发疯想要解决这个问题。

AFTER REGENERATING API KEY 再生API密钥后

I tried regenerating my browser API key on the google console. 我尝试在Google控制台上重新生成浏览器API密钥。

Now when I try to render the page, I get these console errors: 现在,当我尝试呈现页面时,出现以下控制台错误:

primitives.self-5b8a3a6….js?body=1:5 Uncaught ReferenceError: google is not defined(…)Gmaps.Google.Primitives @ primitives.self-5b8a3a6….js?body=1:5Gmaps.Objects.Handler.Handler.setPrimitives @ handler.self-2f220ca….js?body=1:122Handler @ handler.self-2f220ca….js?body=1:8build @ base.self-8dd1d1a….js?body=1:9(anonymous function) @ VM2063:2t.SnapshotRenderer.n.assignNewBody @ turbolinks.self-c5acd7a….js?body=1:6t.SnapshotRenderer.n.replaceBody @ turbolinks.self-c5acd7a….js?body=1:6(anonymous function) @ turbolinks.self-c5acd7a….js?body=1:6t.Renderer.t.renderView @ turbolinks.self-c5acd7a….js?body=1:6t.SnapshotRenderer.n.render @ turbolinks.self-c5acd7a….js?body=1:6t.Renderer.t.render @ turbolinks.self-c5acd7a….js?body=1:6t.View.e.renderSnapshot @ turbolinks.self-c5acd7a….js?body=1:6t.View.e.render @ turbolinks.self-c5acd7a….js?body=1:6t.Controller.r.render @ turbolinks.self-c5acd7a….js?body=1:6(anonymous function) @ turbolinks.self-c5acd7a….js?body=1:6(anonymous function) @ turbolinks.self-c5acd7a….js?body=1:6
turbolinks.self-c5acd7a….js?body=1:6 GET http://google-maps-utility-library-v3.googlecode.com/svn/tags/markerclustererplus/2.0.14/src/markerclusterer_packed.js t.SnapshotRenderer.n.assignNewBody @ turbolinks.self-c5acd7a….js?body=1:6t.SnapshotRenderer.n.replaceBody @ turbolinks.self-c5acd7a….js?body=1:6(anonymous function) @ turbolinks.self-c5acd7a….js?body=1:6t.Renderer.t.renderView @ turbolinks.self-c5acd7a….js?body=1:6t.SnapshotRenderer.n.render @ turbolinks.self-c5acd7a….js?body=1:6t.Renderer.t.render @ turbolinks.self-c5acd7a….js?body=1:6t.View.e.renderSnapshot @ turbolinks.self-c5acd7a….js?body=1:6t.View.e.render @ turbolinks.self-c5acd7a….js?body=1:6t.Controller.r.render @ turbolinks.self-c5acd7a….js?body=1:6(anonymous function) @ turbolinks.self-c5acd7a….js?body=1:6(anonymous function) @ turbolinks.self-c5acd7a….js?body=1:6
turbolinks.self-c5acd7a….js?body=1:6 GET http://localhost:3000/users/assets/images/grayscale.svg t.SnapshotRenderer.n.assignNewBody @ turbolinks.self-c5acd7a….js?body=1:6t.SnapshotRenderer.n.replaceBody @ turbolinks.self-c5acd7a….js?body=1:6(anonymous function) @ turbolinks.self-c5acd7a….js?body=1:6t.Renderer.t.renderView @ turbolinks.self-c5acd7a….js?body=1:6t.SnapshotRenderer.n.render @ turbolinks.self-c5acd7a….js?body=1:6t.Renderer.t.render @ turbolinks.self-c5acd7a….js?body=1:6t.View.e.renderSnapshot @ turbolinks.self-c5acd7a….js?body=1:6t.View.e.render @ turbolinks.self-c5acd7a….js?body=1:6t.Controller.r.render @ turbolinks.self-c5acd7a….js?body=1:6(anonymous function) @ turbolinks.self-c5acd7a….js?body=1:6(anonymous function) @ turbolinks.self-c5acd7a….js?body=1:6
util.js:221 Google Maps API warning: NoApiKeys https://developers.google.com/maps/documentation/javascript/error-messages#no-api-keysuD.S @ util.js:221(anonymous function) @ js?v=3.23&key=:127(anonymous function) @ js?v=3.23&key=:47(anonymous function) @ js?v=3.23&key=:44(anonymous function) @ js?v=3.23&key=:47(anonymous function) @ js?v=3.23&key=:97(anonymous function) @ js?v=3.23&key=:44(anonymous function) @ js?v=3.23&key=:97(anonymous function) @ js?v=3.23&key=:44(anonymous function) @ js?v=3.23&key=:97(anonymous function) @ js?v=3.23&key=:44(anonymous function) @ js?v=3.23&key=:97jc @ js?v=3.23&key=:46gc.Qc @ js?v=3.23&key=:97(anonymous function) @ common.js:1
util.js:221 Google Maps API warning: RetiredVersion https://developers.google.com/maps/documentation/javascript/error-messages#retired-versionuD.S @ util.js:221(anonymous function) @ js?v=3.23&key=:127(anonymous function) @ js?v=3.23&key=:47(anonymous function) @ js?v=3.23&key=:44(anonymous function) @ js?v=3.23&key=:47(anonymous function) @ js?v=3.23&key=:97(anonymous function) @ js?v=3.23&key=:44(anonymous function) @ js?v=3.23&key=:97(anonymous function) @ js?v=3.23&key=:44(anonymous function) @ js?v=3.23&key=:97(anonymous function) @ js?v=3.23&key=:44(anonymous function) @ js?v=3.23&key=:97jc @ js?v=3.23&key=:46gc.Qc @ js?v=3.23&key=:97(anonymous function) @ common.js:1
util.js:221 Google Maps API warning: InvalidKey https://developers.google.com/maps/documentation/javascript/error-messages#invalid-keyuD.S @ util.js:221(anonymous function) @ js?v=3.23&key=:127(anonymous function) @ js?v=3.23&key=:47(anonymous function) @ js?v=3.23&key=:44(anonymous function) @ js?v=3.23&key=:47(anonymous function) @ js?v=3.23&key=:97(anonymous function) @ js?v=3.23&key=:44(anonymous function) @ js?v=3.23&key=:97(anonymous function) @ js?v=3.23&key=:44(anonymous function) @ js?v=3.23&key=:97(anonymous function) @ js?v=3.23&key=:44(anonymous function) @ js?v=3.23&key=:97jc @ js?v=3.23&key=:46gc.Qc @ js?v=3.23&key=:97(anonymous function) @ common.js:1

I can also see when I look in the terminal for rails s: 当我在终端中查看rails时,我还可以看到:

ActionController::RoutingError (No route matches [GET] "/assets/underscore-min.map"):

Parameters: {"id"=>"4"}
ActionController::RoutingError (No route matches [GET] "/users/assets/images/grayscale.svg"):

In relation to the underscore routing error, the line in the terminal refers to assets/underscore. 关于下划线路由错误,终端中的行指的是资产/下划线。 My file structure is vendor/assets/javascripts and then the file is saved as underscore.js (not min.map). 我的文件结构是vendor / assets / javascripts,然后将文件另存为underscore.js(不是min.map)。

ANOTHER ATTEMPT 另一个尝试

I tried replacing the js v3.23 with v3.24 and that got rid of the above warning messages. 我尝试用v3.24替换js v3.23,并且摆脱了以上警告消息。 However, I still can't get aa map to render an address. 但是,我仍然无法获得地图来渲染地址。 When I inspect the chrome console inspector, I can see that the address is acknowledged in the javascript, but the latitude and longitude details are not: 当我检查chrome控制台检查器时,可以看到该地址已在javascript中得到确认,但纬度和经度详细信息却没有:

  handler = Gmaps.build('Google');
  handler.buildMap({ provider: {}, internal: {id: 'map'}}, function(){
    markers = handler.addMarkers([{"lat":null,"lng":null,"infowindow":"Unit 1\u003cbr\u003e34 Darling Street\u003cbr\u003eBuilding D\u003cbr\u003eBalmain East   NSW   2041\u003cbr\u003eAustralia"}]);
    handler.bounds.extendWith(markers);
    handler.fitMapToBounds();
  });

I'm now wondering if this problem might have something to do with the model associations. 我现在想知道这个问题是否与模型关联有关。

I have an address model and an organisation model. 我有一个地址模型和一个组织模型。 The associations are: 关联是:

Address: 地址:

belongs_to :addressable, :polymorphic => true, optional: true

Organisation: 组织:

has_many :addresses, as: :addressable
    accepts_nested_attributes_for :addresses,  reject_if: :all_blank, allow_destroy: true

In my address controller show action, I have: 在我的地址控制器show action中,我有:

def show
        @hash = Gmaps4rails.build_markers(@address) do |address, marker|
          marker.lat user.latitude
          marker.lng user.longitude
          # marker.title user.title
      end
    end

In my organisation controller show action, I have: 在我的组织控制器显示操作中,我有:

    def show
    @addresses = @organisation.addresses

    @hash = Gmaps4rails.build_markers(@addresses) do |address, marker|
        marker.lat address.latitude
        marker.lng address.longitude
        marker.infowindow address.full_address
    end    
  end

The partial with the map in it is in views/addresses/map.html.erb 带有地图的局部视图在views / addresses / map.html.erb中

When I try to render the page again with these changes, I get a lot of errors that all say: 当我尝试通过这些更改再次呈现页面时,出现很多错误,这些错误都说:

js?v=3.24&key=AIzaSyAleQgfNH3HRQVUCYnyAzp46xmXW7WrWrc:37 Uncaught RangeError: Maximum call stack size exceeded

I've read other SO posts where people have had this error and the notes go on to discuss 'recursive loops'. 我读过其他SO帖子,那里的人们都犯了这个错误,并且这些笔记继续讨论“递归循环”。 I don't seem to have any code which is similar to the code shown in those errors, so I'm not sure how to address these messages. 我似乎没有任何与这些错误中显示的代码相似的代码,因此我不确定如何解决这些消息。

I'm wondering if I need to change the organisation controller action to somehow reference the organisation address instead of addresses generally (although if that's the case, then I don't understand how the console inspector shows the correct address being identified in the js from the map partial). 我想知道是否需要更改组织控制器操作以某种方式引用组织地址而不是一般地引用地址(尽管如果是这种情况,那么我不理解控制台检查器如何显示从地图局部)。

Can anyone help with a detailed step by step tutorial that I could use in trying to figure this out? 任何人都可以提供详细的分步教程来帮助我解决这个问题吗?

Others with similar problems 其他有类似问题的人

I can see from other SO posts that others have had similar problems. 从其他SO帖子中可以看出,其他人也有类似的问题。 The advice seems to be this answer: Gmaps4rails Maximum call stack size exceeded? 建议似乎是这样的答案: Gmaps4rails是否超出了最大调用堆栈大小?

I think I've already done this though - my show action in each of the address controller and organisation controller both refer to lat/lng rather than the full words (which are used in the db). 我想我已经做到了-我在地址控制器和组织控制器中的show动作都引用了lat / lng而不是完整的词(在db中使用)。

ERIC'S SUGGESTION 埃里克的建议

Taking Eric's suggestion, I removed gmaps4rails gem from the gem file, and the require/gmaps line from application.js 根据Eric的建议,我从gem文件中删除了gmaps4rails gem,并从application.js中删除了require / gmaps行

I changed the show action of my organisations controller to: 我将组织控制器的显示操作更改为:

def show
    @addresses = @organisation.addresses.all

    # @hash = Gmaps4rails.build_markers(@addresses) do |address, marker|
    #     marker.lat address.latitude
    #     marker.lng address.longitude
    #     marker.infowindow address.full_address
    # end

  end

This step is the same as Eric's suggestion for the index action of his markers controller. 此步骤与Eric对于其标记控制器的索引操作的建议相同。 I separately have an addresses controller which has an index action similar to Eric's. 我分别有一个地址控制器,该控制器具有类似于Eric的索引动作。 In my db, addresses are polymorphic and belong to organisations. 在我的数据库中,地址是多态的,属于组织。 I'm trying to render the map on the organisations show page, so I think this step is consistent with Eric's suggestion. 我正在尝试在组织的显示页面上呈现地图,因此我认为此步骤与Eric的建议一致。

Next I updated my addresses/_map.html.erb with: 接下来,我使用以下命令更新了我的地址/_map.html.erb:

<h3>My Google Maps Demo</h3>
<div id="map"></div>

<%= javascript_tag do %>
  var addresses = <%= raw @addresses.to_json %>;
<% end %>

<script async defer
src="https://maps.googleapis.com/maps/api/js?key=<%= ENV['GOOGLE_MAPS_API_KEY'] %>&callback=initMap">
</script>

I made a new file in my app/javascripts folder for addresses.js, with: 我在app / javascripts文件夹中为addresses.js创建了一个新文件,其内容如下:

   function initMap() {
  var map = new google.maps.Map(document.getElementById('map'), {
    zoom: 4
  });
  var bounds = new google.maps.LatLngBounds();

  var n = addresses.length;
  for (var i = 0; i < n; i++) {
    var address = new google.maps.Address({
      position: {lat: parseFloat(addresses[i].latitude), lng: parseFloat(addresses[i].longitude)},
      title: addresses[i].name,
      map: map
    });
    bounds.extend(address.position);
  }

  map.fitBounds(bounds);
}

When I save all this and try it, an empty grey box appears on the screen. 当我保存所有这些并尝试时,屏幕上会出现一个空的灰色框。

When I use the chrome inspector I can see: 使用镀铬检查器时,我可以看到:

//<![CDATA[

  var addresses = [{"id":5,"unit":"1","building":"d","street_number":"34","street":"darling street","city":"Balmain East","region":"NSW","zip":"2041","country":"AU","time_zone":"International Date Line West","addressable_id":1,"addressable_type":"Organisation","description":"main_address","created_at":"2016-10-27T19:17:27.919Z","updated_at":"2016-11-08T22:48:16.978Z","latitude":"-33.85751","longitude":"151.193546"}];

//]]>

The above is the address in the db. 以上是数据库中的地址。 But it isn't making a map. 但这不是在绘制地图。

Can anyone see what I need to do to get the map to render with the address? 谁能看到我需要做些什么才能使地图与地址一起呈现?

WHEN I LOOK AT THE CHROME CONSOLE INSPECTOR 当我查看铬控制台检查程序时

I can see several new errors in the console inspector. 我可以在控制台检查器中看到几个新错误。

They are: 他们是:

addresses.self-176b72f….js?body=1:9 Uncaught TypeError: google.maps.Address is not a constructor

This post has a similar problem. 这个帖子有类似的问题。 The accepted solution is to add a callback. 可接受的解决方案是添加回调。 I don't know how or where to do that. 我不知道该怎么做或在哪里做。

Google Maps API v3 - TypeError: Result of expression 'google.maps.LatLng' [undefined] is not a constructor Google Maps API v3-TypeError:表达式'google.maps.LatLng'的结果[未定义]不是构造函数

For a start try to get rid from "NoApiKeys", "InvalidKey" errors. 首先,尝试摆脱“ NoApiKeys”,“ InvalidKey”错误。 Have you generated key like its written in this instruction ? 您是否已生成本说明中所写的密钥? Are you sure that you put generated key into ENV['GOOGLE_MAPS_API_KEY'] ? 您确定将生成的密钥放入ENV ['GOOGLE_MAPS_API_KEY']吗?

Here is the smallest Rails app I could get running with Google Maps. 这是我可以在Google Maps上运行的最小的Rails应用程序。

Ruby 2.3.1, Rails 5.0.0.1, no extra gem needed. Ruby 2.3.1,Rails 5.0.0.1,不需要额外的gem。

rails new gmaps

uncomment 取消评论

gem 'therubyracer', platforms: :ruby

in Gemfile 在Gemfile中

bundle install

rails generate resource marker name:string latitude:decimal longitude:decimal

rake db:migrate

app/controllers/markers_controller.rb: app / controllers / markers_controller.rb:

class MarkersController < ApplicationController
  def index
    @markers = Marker.all
  end
end

app/views/markers/index.html.erb: app / views / markers / index.html.erb:

<h3>My Google Maps Demo</h3>
<div id="map"></div>

<%= javascript_tag do %>
  var markers = <%= raw @markers.to_json %>;
<% end %>

<script async defer
src="https://maps.googleapis.com/maps/api/js?key=<%= ENV['GOOGLE_MAPS_API_KEY'] %>&callback=initMap">
</script>

app/assets/stylesheets/markers.scss: 应用程序/资产/样式表/markers.scss:

#map {
  height: 400px;
  width: 100%;
}

app/assets/javascripts/markers.js: app / assets / javascripts / markers.js:

function initMap() {
  var map = new google.maps.Map(document.getElementById('map'), {
    zoom: 4
  });
  var bounds = new google.maps.LatLngBounds();

  var n = markers.length;
  for (var i = 0; i < n; i++) {
    var marker = new google.maps.Marker({
      position: {lat: parseFloat(markers[i].latitude), lng: parseFloat(markers[i].longitude)},
      title: markers[i].name,
      map: map
    });
    bounds.extend(marker.position);
  }

  map.fitBounds(bounds);
}

Add some Markers in rails c : rails c添加一些标记:

Marker.create(:name => 'Sydney', :latitude => -33.87, :longitude => 151.17)
Marker.create(:name => 'Uluru', :latitude => -25.363, :longitude => 131.044)

Add your API KEY to the environment in bash : 在bash中将您的API KEY添加到环境中:

export GOOGLE_MAPS_API_KEY="AIza.............................."

rails s

Done! 做完了!

I used this answer and this Gmaps documentation . 我用了这个答案和这个Gmaps文档

You probably should check that no malicious code is transmitted to javascript, eg via Marker#name. 您可能应该检查是否没有恶意代码例如通过Marker#name传输到javascript。

Hopefully you have it sorted but is seems like your JS is wrong for your api key. 希望您已经对它进行了排序,但是看来您的JS错误是您的api键。 Were you getting an OOPS error? 您收到OOPS错误吗? You need to use an updated version with 'v=3' in it. 您需要使用其中带有“ v = 3”的更新版本。

<script src="//maps.google.com/maps/api/js?v3key=[API_KEY]"></script>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM