Rails - 在链接点击时更改布尔值

时间:2013-12-13 03:28:49

标签: ruby-on-rails ruby ajax twitter-bootstrap ruby-on-rails-4

在我的应用中,我有用户通知,用户会收到某些操作的通知。这些通知显示在导航栏的下拉列表中(如Facebook或S.O.)。所有通知都有一个名为read的布尔属性,默认设置为false。我正在使用带有下拉列表的bootstrap(如果有帮助的话)。
我想创建一种方法,当用户单击以打开下拉列表时,将读取所有未读通知。

这是我到目前为止的方法。

def read_notifications
  PublicActivity::Activity.where(recipient_id: current_user).where(read: false).update_all(:read => true)
end

这会将所有当前用户的通知更新为:read =>调用方法时为true。在视图中,这是我到目前为止的下拉链接。

<%= link_to read_notifications_path, :class => "dropdown-toggle notifications_icon", :'data-toggle' => "dropdown", :controller => "application", :action => "read_notifications", :method => :post do %><% end %>

和routes.rb我有这个。

match "/read" => "application#read_notifications", :as => "read_notifications", via: 'post'

现在我知道我的错误,但即便如此,当我点击链接时它会将所有用户的通知切换为读取,它只是作为一个链接(duh)并转到另一个页面。
如您所知,引导下拉列表中的链接为“#”。

当用户点击导航栏中的通知链接时,有没有人知道如何正确设置它,所有它都打开下拉列表并将所有通知的布尔值更改为true。

我知道这是可能的,我还没有弄清楚。
谢谢你看看它。

修改

JS档案

$(".notifications_icon").on("click", function(){
  $.post("/read", function(data){
    $('.notification_badge').text("");
  });
});

查看

<%= link_to "#", :class => "dropdown-toggle notifications_icon", :'data-toggle' => "dropdown" do %>
  <span class="notification_badge"><%= find_unread_notifications_count(current_user) %></span>
<% end %>

这是发布到/读取所有通知,但它没有更新计数

2 个答案:

答案 0 :(得分:1)

你需要一些不引人注目的JS 。例如,SO有一个类js-inbox-button,当单击它时,会触发未读计数(客户端和服务器)的更新。我不会深入研究他们的JS源代码,但构建起来相当简单。

您似乎已经拥有相关的类(notifications_icon),但您可能想要使用其他类。单击链接后,使用jquery $.post

$(".notifications_icon").on("click", function(){
  $.post("/read", function(data){
    // remove unread count
    $('.notification_badge').text('');
  });
});

现在这是一个非常基本的实现。几点建议:

  1. 仅在必要时发出请求(首先检查未读计数)
  2. 使用链接上的数据属性传递/read路径。这样你仍然可以使用路径助手,而不是硬编码路径。
  3. 将上述JS存储在单独的文件中(不显眼)

答案 1 :(得分:1)

AJAX。

通过添加remote: true,您将开始使用AJAX。现在,呼叫进入你的道路,没有任何反应!耶!

但是你想要发生一些事情。所以在你的控制器中(我不会在application_controller中这样做,如果我是你......可能是activities_controller.rb?):

<强>控制器/ activities_controller.rb

def read_notifications
  PublicActivity::Activity.where(recipient_id: current_user).where(read: false).update_all(:read => true)
  respond_to do |format|
    format.js
  end
end

您正在前往异步加载!现在你需要一个js文件来匹配它。因此,既然您已经将此操作移动到了活动,那么在您的视图中,您将创建一个新的js.erb文件(请注意它与视图中的控制器名称位于视图中的相同文件夹中,并且文件是以行动命名):

<强>视图/活动/ read_notifications.js.erb

$('#your_menu_div').html("<%= j render partial: 'activities/notifications' %>");

现在你创建一个部分(views/activities/_notifications.html.erb),它会被渲染到你的下拉菜单中。

清除泥土?