Wes Creations
Wes Creations

Reputation: 387

How do I mark notification as read when clicking on link? (rails)

I have a notification system in my rails app. On my notifications model I have:

message user_Id read link_path

The following code works great for showing me the notifications for the current user, and then showing me the notifications that are read. I'm looping through each of these records where this criteria is true, and then doing a link_to @link do, and then outputting the whole code.

Basically the whole block I can then click on and it will take me to the proper record. That works like a charm.

The default for all new notifications is :read => false.

However, when user clicks on the link, I'm trying to pass :read => true into that record, so that when I come back that particular notification will no longer show, since it's only showing me :read => false notifications.

What is the easiest way to go about this? I've tried wrapping everything in a form_for and trying to pass this value of :read => true into the record, but I can't get that to work. Thoughts?

Controller

    @x = Notification.where(:user_id =>  current_user, :read => false)

View

   <% @x.where(:user_id =>  current_user).each do |notify| %> 

   <% @link = notify.link_path %> 

   <%= link_to @link do %>
   <div class="row notifyrow">
     <div class="col-sm-7">
       <p> <%= notify.message %></p>
     </div>
     <div class="col-sm-3">
       <p> <%= time_ago_in_words(notify.created_at )%> ago</p>
     </div>       
   </div>
  <% end %> 
  <% end %> 

Upvotes: 0

Views: 1154

Answers (1)

rmlockerd
rmlockerd

Reputation: 4136

What you seem to want to do is to update the read attribute on a particular Notification when the user clicks the link. That's absolutely what a Controller method is for. For example, assuming the route for your notify_link is something akin to get '/notifications/:id', to: 'notifications#show', you'd do the following:

class NotificationsController < ApplicationController
  ...
  def show
    @notice = Notification.find(params[:id])
    @notice.update!(read: true)
  end
end

That updates the read attribute on the record, so when you go back to the main view it will no longer appear in your unread list.

By the way, in your controller you run a query to get all the unread notifications for the current user, and then run where() again in your view. It should be sufficient to just do @x.each in your view.

EDIT

To summarise the comments discussion below, since the linked path doesn't include the Notification object ID, you just need to include it in the query parameters. The Rails-generated URL helpers take a hash (following any parameters required to complete the path) and includes them in the query string. So, something like:

national_race_path(@national_race.id, notify_id: notify.id)

will append the ID as <whatever_path>?notify_id=1234 and it will be accessible in the controller via params[:notify_id]. You'll need to handle what happens if no or invalid ID is passed, etc., but that should give you what you need.

Upvotes: 3

Related Questions