将Private-pub与具有段键和coffeescript变体的频道一起使用

时间:2014-01-14 00:57:18

标签: ruby-on-rails ruby-on-rails-4 coffeescript private-pub gritter

我正在尝试使用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响应

3 个答案:

答案 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变量。

希望能回答你的问题。