The Rails Way: отправка клиентских данных контроллеру с помощью турболыков

Что такое «способ Rails» для отправки данных в действие контроллера при простом событии щелчка при использовании турболыков?

У меня есть страница с двумя ссылками: одна указывает на /food, а другая - на /drinks. Моя цель - отправить некоторые данные о местоположении (через geolocation api) контроллеру, а затем отобразить соответствующее представление после обработки этих данных о местоположении.

Каков путь наименьшего сопротивления, чтобы направить пользователя по соответствующему пути и отправить данные вместе с запросом?

Следует ли каждую кнопку обернуть в форму и отправить запрос по почте?

Должен ли я захватить / отключить Turbolinks и самостоятельно управлять рендерингом? Если я просто отправлю данные через XHR о событии щелчка, контроллер получит 2 запроса: один от Turbolinks, а другой от моего обработчика, что нежелательно.

Вот код:

app / controllers / drinks_controller.rb

class DrinksController < ApplicationController
  def index
    # Ideally, I would like to check for POST or GET data here 
    # and send as a parameter to get_a_venue

    @venue = get_a_venue(:drinks)
  end
end

приложение / просмотры / напитки / index.html.erb

<% provide(:title, @venue[:name]) %>

<!-- body content -->

<div class="row buttons">
    <div class="small-12 medium-6 columns">
        <h3>
            <%= link_to 'Try Another One', drinks_path, class: "button expand radius choice" %>
        </h3>
    </div>
    <div class="small-12 medium-6 columns">
        <h3>
            <%= link_to "I Want Some Food Instead", food_index_path, class: "button expand radius choice" %>
        </h3>
    </div>
</div>

app / assets / javascripts / handlers.js

$(function() {
    // success callback sets an in scope variable to the location coordinates
    navigator.geolocation.getCurrentPosition(success, error, options)

    document.addEventListener('click', function(e) {
        if (e.currentTarget.nodeName === 'A' &&
            e.currentTarget.classList.contains('choice') {

            // send data via ajax here?
        }
    }, false)
 })()

person Brian Whitton    schedule 10.04.2014    source источник


Ответы (1)


Вы можете, например, отказаться ваши кнопки, которые не позволят вашим кнопкам использовать турболинки.

Или вы можете прослушать событие page:before-change, выполнить запрос AJAX и вернуть false. Это отменит запрос турболинка. Источник

Так что-то вроде:

document.addEventListener('page:before-change', function(e) {
  if (e.currentTarget.nodeName === 'A' &&
      e.currentTarget.classList.contains('choice') {
     // do stuff
  }
  return false;
}, false)

Если вы хотите использовать турболинки, но предоставить геолокацию в виде строки запроса для вашего контроллера, вы можете сделать link_to "something", something_path(lat: <geolat>, lng: <geolng>), а затем получить доступ к широте, долготе с помощью params[:lat], params[:lng]

person drowzy    schedule 10.04.2014
comment
Прохладный. Итак, вы думаете, что лучший способ - отказаться от использования Turbolinks и обрабатывать изменение страницы в контроллере с помощью render или redirect_to? - person Brian Whitton; 10.04.2014
comment
Конечно, или с link_to, если вы хотите, чтобы турболинки оставались активными. См. Обновленный ответ. - person drowzy; 11.04.2014
comment
В итоге я отправил запрос POST независимо от щелчка по ссылке. Итак, пользователь приходит, затем мы получаем геоданные и отправляем их методу контроллера, который сохраняет данные как переменную сеанса. Можно по-прежнему использовать турболинки, и данные сохраняются между страницами. - person Brian Whitton; 11.04.2014