I've created a page that allows a company to view a users answer to an application .
If the user have created an application, and a user has answered it, it will show up on the page. Displaying their answer, who answered it and what time they answered it.
What I would like to do is add a notification system on the link to this page so that it is possible for the company to know when a new user has answered their application, without having to be / visit the page.
The page is straight forward.
companies_controller:
def applicants
@applications = current_company.applications.order("created_at DESC")
end
applicants.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 %>
Each company when signed in have the ability to visit the applicants page through their navigation in the header. Ideally I'd want a counter (1,2,3) next to it for example. Depending on the amount of new users that have applied. How can I create this?
Live
From my understanding here (you want a stateless piece of functionality which updates notifications after they are made)?
If so, I would recommend looking into websockets
/ live
functionality. This basically allows you to show different triggers when your application acts in a particular way. IE you want to use push notifications
or similar
JS
There are a number of ways to achieve this, all using the same pattern - use JS on the front-end to "listen" for any updates from the server.
The server will then send the updates asynchronously (using something such as websockets
, SSE
's or similar). One the message has been sent, the JS "listener" will essentially "catch" the message & follwo your functionality to process it.
A good example is here :
source = new EventSource('your/endpoint');
source.addEventListener('message', function(e) {
console.log(e.data);
}, false);
This is covered using the ActionController::Live
functionality in Rails, but is much better handled by a third party at the moment (sad but true)
--
Events
There are several things for you to look at:
Server Sent Events are a HTML5 feature, basically allowing you to send asynchronous messages from the server to your front-end:
A server-sent event is when a web page automatically gets updates from a server.
This was also possible before, but the web page would have to ask if any updates were available. With server-sent events, the updates come automatically.
Examples: Facebook/Twitter updates, stock price updates, news feeds, sport results, etc.
This is not through Ajax - it's through HTTP with JS, and is handled using the text/event-stream
header. You'd handle it like this:
#config/routes.rb
resources :your_controller do
collection do
get :messages #-> domain.com/your_controller/messages
end
end
If you set JS to "listen" to that URL, you'll be able to "catch" any information you send from the server, like this:
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
This will allow you to use the javascript like this:
var source = new EventSource("/your_controller/messages");
source.onmessage = function(event) {
alert ("message");
};
--
Although the SSE route is "native" to HTML5 (except for IE), it's basically a glorified version of Ajax Long-Polling , basically meaning your browser is going to be pinging your server every second for updates. LAME
A much more robust way is to use websockets
, which essentially creates a perpetual connection between your browser & the server. Although we've not got this working natively in Rails yet, we have found a system called Pusher which can handle it
Pusher is a plugin which basically creates a websocket
through their servers. This means you can include their gem
, allowing you to converse with your front-end (in a much similar way to 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);
});
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.