#ruby-on-rails #ruby-on-rails-4
#ruby-on-rails #ruby-on-rails-4
Вопрос:
Я создал страницу, которая позволяет компании просматривать ответы пользователей на приложение.
Если пользователь создал приложение, и пользователь ответил на него, оно отобразится на странице. Отображение их ответа, кто на него ответил и в какое время они на него ответили.
Что я хотел бы сделать, так это добавить систему уведомлений по ссылке на эту страницу, чтобы компания могла знать, когда новый пользователь ответил на их заявку, без необходимости находиться / посещать страницу.
Страница является прямой.
companies_controller:
def applicants
@applications = current_company.applications.order("created_at DESC")
end
кандидаты.html.erb:
<% @applications.all.each do |application| %>
<% application.answers.each do |answer| %>
<p>Your question1: <%= answer.application.question_1 %></p>
<p>Their answer 1: <%= answer.answer_1 %></p>
<p>Your question 2: <%= answer.application.question_2 %></p>
<p>Their answer 3: <%= answer.answer_2 %></p>
<p>Your question 3: <%= answer.application.question_3 %></p>
<p>Their answer 3: <%= answer.answer_3 %></p>
<i>Answered by <b><%= link_to "#{answer.user.fullname}", user_path(answer.user.slug) %></b>, <%= time_ago_in_words(answer.created_at) %> ago</i> | <%= button_to "delete this applicant", root_url, data: { confirm: "Are you sure?"}, method: :delete %>
<hr>
<% end %>
<% end %>
Каждая компания, вошедшая в систему, имеет возможность перейти на страницу кандидатов с помощью навигации в заголовке. В идеале я бы хотел, чтобы рядом с ним был счетчик (1,2,3), например. В зависимости от количества новых пользователей, которые подали заявку. Как я могу это создать?
Комментарии:
1. Вам нужен счетчик, на котором? по вопросу?
2. @Pavan да, если был создан новый ответ на вопрос (который принадлежит current_company)
3.
counter_cache
могло бы быть решением для вас, но я не понимаю, как применить это к вашему вопросу.
Ответ №1:
ЖИВЫЕ КОНЦЕРТЫ
Насколько я понимаю (вам нужна функциональность без состояния, которая обновляет уведомления после их создания)?
Если это так, я бы рекомендовал изучить websockets
/ live
функциональность. По сути, это позволяет вам показывать разные триггеры, когда ваше приложение действует определенным образом. IE, который вы хотите использовать push notifications
или аналогичный
JS
Существует несколько способов добиться этого, все с использованием одного и того же шаблона — используйте JS во внешнем интерфейсе, чтобы «прослушивать» любые обновления с сервера.
Затем сервер будет отправлять обновления асинхронно (используя что-то вроде websockets
, SSE
‘s или аналогичное). После отправки сообщения «прослушиватель» JS, по сути, «поймает» сообщение и воспользуется вашей функциональностью для его обработки.
Хороший пример здесь:
source = new EventSource('your/endpoint');
source.addEventListener('message', function(e) {
console.log(e.data);
}, false);
Это описано с использованием ActionController::Live
функциональности Rails, но на данный момент гораздо лучше обрабатывается третьей стороной (печально, но факт)
—
Мероприятия
Есть несколько вещей, на которые вам следует обратить внимание:
SSE (события, отправленные сервером)
События, отправляемые сервером, — это функция HTML5, в основном позволяющая вам отправлять асинхронные сообщения с сервера на ваш интерфейс:
Событие, отправляемое сервером, — это когда веб-страница автоматически получает обновления с сервера.
Это также было возможно раньше, но веб-страница должна была спрашивать, доступны ли какие-либо обновления. При событиях, отправляемых сервером, обновления приходят автоматически.
Примеры: обновления Facebook / Twitter, обновления цен на акции, новостные ленты, спортивные результаты и т.д.
Это не через Ajax — это через HTTP с JS, и обрабатывается с помощью text/event-stream
заголовка. Вы бы справились с этим следующим образом:
#config/routes.rb
resources :your_controller do
collection do
get :messages #-> domain.com/your_controller/messages
end
end
Если вы настроите JS на «прослушивание» этого URL, вы сможете «перехватывать» любую информацию, отправляемую с сервера, вот так:
class MyController < ActionController::Base
include ActionController::Live
def message
response.headers['Content-Type'] = 'text/event-stream'
sse = SSE.new(response.stream, retry: 300, event: "event-name")
sse.write({ name: 'John'})
sse.write({ name: 'John'}, id: 10)
sse.write({ name: 'John'}, id: 10, event: "other-event")
sse.write({ name: 'John'}, id: 10, event: "other-event", retry: 500)
ensure
sse.close
end
end
Это позволит вам использовать javascript следующим образом:
var source = new EventSource("/your_controller/messages");
source.onmessage = function(event) {
alert ("message");
};
—
Хотя маршрут SSE является «родным» для HTML5 (за исключением IE), по сути, это улучшенная версия Ajax с длительным опросом, что в основном означает, что ваш браузер будет каждую секунду запрашивать обновления на вашем сервере. ОТСТОЙ
Гораздо более надежный способ — использовать websockets
, который по сути создает постоянное соединение между вашим браузером и сервером. Хотя в Rails это еще не работает изначально, мы нашли систему под названием Pusher, которая может с этим справиться
Pusher — это плагин, который в основном создает websocket
через свои серверы. Это означает, что вы можете включить их gem
, что позволит вам взаимодействовать с вашим интерфейсом (во многом аналогично Redis):
#app/controllers/my_controller.rb
Class MyController < ApplicationController
def your_action
Pusher.trigger('my-channel', 'my-event', {
message: 'hello world'
});
end
end
#app/assets/javascripts/application.js
var channel = pusher.subscribe('my-channel');
channel.bind('my-event', function(data) {
alert('Received my-event with message: ' data.message);
});