You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Ruby on Rails 7中Google Maps Places经纬度无法填充表单

问题:Rails 7 + Google Places Autocomplete 无法填充经纬度字段

我有一个Ruby on Rails 7应用,用Google Maps Places Autocomplete API自动填充表单里的酒吧名称、地址、网站等字段,之前运行正常。现在想添加纬度(lat)和经度(lng)字段到表单,保存到数据库后在站点其他地方显示地图标记,但经纬度就是填不到表单里。我已经加了文本字段用来测试(生产环境会改成隐藏字段),控制台里能看到Google Places返回了经纬度数据,但就是没法填充到表单。


相关代码

1. Stimulus控制器 /app/javascript/controllers/places_controller.js

import { Controller } from "@hotwired/stimulus";

export default class extends Controller {
  static targets = [ "field" ]

  connect() {
    if (typeof(google) != "undefined") {
    this.initPlaces()
    }
  }

  initPlaces() {
    this.autocomplete = new google.maps.places.Autocomplete(this.fieldTarget)
    this.autocomplete.setFields(['address_components', 'geometry', 'website', 'name'])
    this.autocomplete.addListener('place_changed', this.fillInAddress.bind(this))
  }

  placeChanged() {
    let place = this.autocomplete.getPlace()
    if (!place.geometry) {
      window.alert(`No details available for input: ${place.name}`)
      return
    }
  }

  keydown(event) {
    if (event.key == "Enter") {
      event.preventDefault()
    }
  }

  fillInAddress() {
    const place = this.autocomplete.getPlace();
    console.log("Place selected:", place);

    if (place.geometry && place.geometry.location) {
      const lat = place.geometry.location.lat();
      const lng = place.geometry.location.lng();

      console.log("Latitude before setting field:", lat);
      console.log("Longitude before setting field:", lng);

      document.querySelector("#bar_info_latitude").value = lat;
      document.querySelector("#bar_info_longitude").value = lng;

      console.log("Latitude after setting field:", document.querySelector("#bar_info_latitude").value);
      console.log("Longitude after setting field:", document.querySelector("#bar_info_longitude").value);
    } else {
      console.log("Selected place does not have geometry or location");
    }

    let bar_info_addressline1 = "";
    document.querySelector("#bar_info_barname").value = place.name
    document.querySelector("#bar_info_website").value = place.website

    for (const component of place.address_components) {
      const componentType = component.types[0];
      switch (componentType) {
        case "street_number": {
          bar_info_addressline1 = `${component.long_name} ${bar_info_addressline1}`;
          break;
        }
        case "route": {
          bar_info_addressline1 += component.short_name;
          break;
        }
        case "postal_code": {
          document.querySelector("#bar_info_zip").value = component.long_name;
          break;
        }
        case "locality":
          document.querySelector("#bar_info_city").value = component.long_name;
          break;
        case "administrative_area_level_1": {
          document.querySelector("#bar_info_state").value = component.short_name;
          break;
        }
      }
    }
    document.querySelector("#bar_info_addressline1").value = bar_info_addressline1;
    document.querySelector("#bar_info_addressline2").focus();
  }
}

2. 表单部分代码 _form.html.erb

<div class="row">
    <div class="col-md 6">
        <%= form_with(model: @bar_info, local: true, data: { controller: "places" }) do |f| %>
        <%= render 'shared/error_messages', object: f.object %>

        <%= f.label "Bar Name (required)" %>
        <%= f.text_field :barname, placeholder: "Bar name here", class: "form-control", size: "70x1", data: { places_target: "field", action: "keydown->places#keydown" } %>

        <% if is_an_admin? || cmdr_user? %>
        <!-- Only admin and cmdr_user gets to use autocomplete feature, to save on google cloud costs -->

        <div class="form-group">
        <%= f.label :address %>
        <%= f.text_field :addressline1, class: 'form-control' %>

        <%= f.label "Address Line 2" %>
        <%= f.text_field :addressline2, placeholder: "Street Address 2", class: "form-control", size: "70x1" %>
        <% end %>

        <%= f.label "City (required)" %>
        <%= f.text_field :city, placeholder: "City", class: "form-control", size: "70x1" %>

        <%= f.label "State (required)" %>
        <%= f.text_field :state, placeholder: "State", class: "form-control" %>

        <% if is_an_admin? || cmdr_user? %>
        <%= f.label :zip %>
        <%= f.text_field :zip, placeholder: "Postal Code", class: "form-control", size: "70x1" %>
        <% end %>

        <p class="mt-2">Not required, but would love to have the information below too!</p>

        <%= f.label :website %>
        <%= f.url_field :website, placeholder: "https://www.example.com", class: "form-control" %>

        <%= f.label :instagram %>
        <div class="input-group mb-3">
            <span class="input-group-text" id="basic-addon1">@</span>
            <%= f.text_field :instagram, placeholder: "username", class: "form-control" %>
        </div>
        <br>

        <%= f.text_field :latitude %>
        <%= f.text_field :longitude %>

        </div>

        <% if is_an_admin? || cmdr_user? %>
        <span class="image">
            <p>Upload an image of Bar here!</p>
            <%= f.file_field :image, accept: "image/jpeg,image/gif,image/png",
                data: { controller: "image-upload", image_upload_target: "image", action: "change->image-upload#checkSize" },
                class: "form-control mb-3", id: "formFile" %>
        </span>
        <% end %>

        <%= f.submit "Submit", class: "btn btn-primary" %>
        <% end %>
    </div>
</div>

3. 经纬度字段的HTML输出

<input type="text" name="bar_info[latitude]" id="bar_info_latitude">
<input type="text" name="bar_info[longitude]" id="bar_info_longitude">

4. Google Places API返回的经纬度数据

"geometry" : 
{
   "location" : 
   {
      "lat" : 34.0532482,
      "lng" : -118.2505517
   },

已确认的情况

  • 控制台能看到API返回了正确的经纬度数据
  • 表单其他字段(名称、地址、网站等)均可正常自动填充
  • JS中使用的选择器与经纬度字段的ID完全匹配

内容的提问来源于stack exchange,提问作者Splohr

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 01:32:25