Как использовать AJAX-запрос для передачи местоположения пользователя HTML5 в переменной класса из JavaScript в контроллер Rails?

#javascript #html #ruby-on-rails #geolocation #geokit

#javascript #HTML #ruby-on-rails #геолокация #geokit

Вопрос:

Я использую Ruby (2.7.2p137), Ruby on Rails (v6.0.3.4) и Geokit-rails (2.3.2).

Я пытаюсь передать местоположение пользователя в метод из Geokit-rails gem. Для этого я пытаюсь использовать AJAX-запрос для передачи местоположения пользователя HTML5 из JavaScript в Rails controller.

Обновление: для этого требовались переменные класса, а не переменные экземпляра. Это объясняется в ответе.

Ниже приведена ошибка / ответ от сервера при вызове метода show_location:

 Started GET "/show_location?user_location[{:value=>nil}]=" for ::1 at 2021-02-21 13:03:18  0000
Processing by PropertiesController#show_location as HTML
  Parameters: {"user_location"=>{"{:value=>nil}"=>""}}
Completed 500 Internal Server Error in 2ms (ActiveRecord: 0.0ms | Allocations: 1235)  
  
NoMethodError (undefined method `*' for nil:NilClass):

app/controllers/properties_controller.rb:77:in `show_location'
 

На сервере отображается следующий ответ, поэтому JavaScript в index.js похоже, это работает:

 Started POST "/user_long" for ::1 at 2021-02-21 12:57:13  0000
Started POST "/user_lat" for ::1 at 2021-02-21 12:57:13  0000
Processing by PropertiesController#user_lat as */*
  Parameters: {"lat"=>"53.3200896"}
No template found for PropertiesController#user_lat, rendering head :no_content
Completed 204 No Content in 80ms (ActiveRecord: 0.0ms | Allocations: 2885)


Processing by PropertiesController#user_long as */*
  Parameters: {"long"=>"-6.2521344"}
No template found for PropertiesController#user_long, rendering head :no_content
Completed 204 No Content in 34ms (ActiveRecord: 0.0ms | Allocations: 2340)
 

Вот объект местоположения HTML5, зарегистрированный в консоли в браузере:

 Object
latitude: 53.3200896
longitude: -6.2521344
__proto__: Object
 

Ниже приведен JavaScript из моего index.js файл, который запрашивает расположение HTML5:

 //function that gets the location and returns it
function getLocation() {
  if(navigator.geolocation) {
    navigator.geolocation.getCurrentPosition(showPosition);
  } else {
    console.log("Geo Location not supported by browser");
  }
}

//function that retrieves the position
function showPosition(position) {
  var location = {
    latitude: position.coords.latitude,
    longitude: position.coords.longitude
  }

  $(document).ready(function() {
    var lat = $(this).val();
    $.ajax({
        type: 'post',
        url: '/user_lat',
        data: {lat: position.coords.latitude},
    success: function(data) {
      console.log(data);
    }
    });      
  })

  $(document).ready(function() {
    var long = $(this).val();
    $.ajax({
        type: 'post',
        url: '/user_long',
        data: {long: position.coords.longitude},
    success: function(data) {
      console.log(data);
    }
    });      
  })

  console.log(location)
}

//request for location
getLocation();
 

Это метод в моем контроллере Rails (properties_controller.rb), который показывает список свойств по расстоянию на основе заданных координат:

 def show_location

    @user_lat = user_lat

    @user_long = user_long

    @properties = Property.by_distance(:origin => [@user_lat, @user_long])

end
 

Вот методы в моем контроллере свойств для запроса AJAX:

   def user_lat
    @user_lat = params["lat"]
  end

  def user_long
    @user_long = params["long"]
  end
 

Я знаю, что gem и контроллер работают, потому что, когда я жестко кодирую координаты в метод show_location , он работает успешно. Рабочий метод ниже.

   def show_location
    
    @properties = Property.by_distance(:origin => [53.3200896,-6.2521344])

  end
 

Итак, мне просто нужна помощь, чтобы передать местоположение пользователя в этот метод.

С помощью приведенного выше кода я получаю следующую ошибку:

 undefined method `*' for nil:NilClass
 

относящийся к строке:

 @properties = Property.by_distance(:origin => [@user_lat, @user_long])
 

Любая помощь приветствуется.

Комментарии:

1. Прочитайте о том, как использовать ajax для отправки данных с клиента на сервер

2. Вам нужно отправить его, showPosition() поскольку geolocation.getCurrentPosition() он асинхронный

Ответ №1:

Я понял это. Запрос AJAX работал, однако методы внутри properties_controller сохраняли широту и долготу пользователя в переменных экземпляра, а не в переменных класса.

Переменные экземпляра не могут использоваться / доступны вне метода, тогда как переменные класса могут использоваться / доступны в любом методе внутри класса.

Это исправлено ниже в properties_controller.rb :

   def user_lat
    @@user_lat = params["lat"]
    session[:user_lat] = @@user_lat
  end

  def user_long
    @@user_long = params["long"]
    session[:user_long] = @@user_long
  end
 

Затем переменные класса передаются в метод show_location .

 def show_location
    @properties = Property.by_distance(:origin => [@@user_lat, @@user_long])
end