我正在尝试使用private_pub复制类似于facebook的推送通知系统。理想情况下,我想链接此以显示使用诸如gritter之类的gem的通知(欢迎其他宝石建议)
每当调用控制器的某个操作时,我都希望向属于特定ID的所有订阅者发送通知。只要您登录,就可以订阅频道,方法是将subscribe_to
放在布局中。
在视图中:
<%= subscribe_to "/messages/#{@group_id}" %>
控制器中的
PrivatePub.publish_to("/messages/#{@group_id}", "alert('test')")
这很好用,但是我希望有一些比alert
更复杂的东西作为回应(比如一个砂砾通知),所以相反:
PrivatePub.publish_to("/messages/#{@group_id}", data: @some_data)
在tutorial之后,他们使用coffeescript。但是,我无法获得简单的警报(可能是由于频道中的id)
在this问题中,OP能够使用js.erb视图解决此问题。但我无法让它发挥作用。
免责声明:我的js和coffeescript知识几乎为零。感谢任何帮助:)
修改
更多信息:我在控制器中有一个方法,它是公共API的一部分,并且需要POST请求。如果一切正常,它会发出JSON成功响应。除此之外,相同的方法会向特定组的所有用户发送通知。
我实际上设法让这个工作,把它放在控制器中:
回调方法:
respond_to do |format|
format.js #-> calls callback.js.erb
#format.json { render json: {"success" => true}.to_json }
end
并将gritter内容放入my_api_controller/callback.js.erb
:
<% publish_to "/messages/#{@group_id}" do %>
<%= add_gritter(
"Nova " + link_to("reserva", reservation_path(@r)) + " de #{@channel} para " +
link_to(@hostel_name, hostel_path(@hostel_id)),
:title => "Nova reserva!",
:sticky => true,
:image => :notice
) %>
<% end %>
注意:由于频道订阅是在每个视图中完成的(通过布局),您可以在任何页面/视图上收到通知
正如你所能想到的那样,我的问题是JSON响应。由于我无法呈现两个响应,因此只调用js.erb,但永远不会发送JSON响应
答案 0 :(得分:1)
虽然我对这个宝石没有多少经验,但这里有一些可能有用的东西:
<强> JS 强>
客户端,您的JS基本上在private_pub
对象上运行eventlistener
(在您的页面上包含private_pub
/ gritter
JS时定义),您可以用来执行其他操作(调用警报,将数据附加到页面等)
看来你的后端正在工作,这只是收据&amp;从您正在努力的服务器处理数据。要解决这个问题,您可以做两件事:1)从application.js
运行标准JS调用或从控制器操作运行js文件:
<强>控制器强>
根据private_pub
文档,您应该这样做以创建一个JS文件:
#app/controllers/your_controller.rb
def create
@message = "Hello"
respond_to do |format|
format.html { PrivatePub.publish_to("/messages/#{@group_id}", "alert('test')") }
format.js #-> calls create.js.erb
end
end
#app/views/your_controller/create.js.erb
<% publish_to "/messages/new" do %>
$("#chat").append("<%= j render(@messages) %>");
<% end %>
<强>浏览器强>
#app/assets/javascripts/application.js.coffee
PrivatePub.subscribe("/messages/new", (data, channel) ->
alert data.message.content
答案 1 :(得分:1)
我能够通过在Privat pub的publish_to
方法中直接添加gritter脚本来实现此目的。
在我的控制器中:
PrivatePub.publish_to
"/some/URI/#{entity.id}"
,"jQuery.gritter.add({
image: '#{ActionController::Base.helpers.asset_path('notice.png')}'
, sticky: true
,title:'#{t('some_title')}'
, text: '#{t('some text'}'
});"
render json: {"error"=>{"code"=>20,"msg"=>e.message},"success" => false}.to_json
基本上,我能够通过html响应发布到PrivatePub,这使我能够按预期返回JSON响应。
答案 2 :(得分:0)
我想,您可以在gon gem的帮助下处理您的问题,如下所示:
In view
<%= subscribe_to "/messages/#{@group_id}" %>
In controller
gon.group_id = @group_id
PrivatePub.publish_to("/messages/#{@group_id}", message: @message)
In messages.coffee
if gon.group_id
PrivatePub.subscribe "/messages/#{gon.group_id}", (data, channel) ->
jQuery.gritter.add
image: '/assets/notice.png'
title: 'Notification!'
text: data.message.content
但是,gon.group_id
有时会制造麻烦,所以你需要照顾它。
因此,我建议您使用js.erb
,这很容易,我们可以在controller's
文件中轻松访问js.erb
变量。
希望能回答你的问题。