0

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 %> 
Wes Creations
  • 337
  • 2
  • 10
  • So all you're trying to do is append `?read=true` to the link? – max pleaner Jul 01 '20 at 00:33
  • I don’t know is that all I need to do? This problem seems real simple and I’m just not sure. Would appending that to the link update the record so that it’s read attribute now had value of true ? – Wes Creations Jul 01 '20 at 00:37
  • Appending that to the link would cause the `read` parameter to be send with the GET request, and it would have a value `"true"`. I guess you can just pass `read: true` parameter to the `link_to` method. See https://stackoverflow.com/questions/2695538/add-querystring-parameters-to-link-to – max pleaner Jul 01 '20 at 00:40
  • Once you sent the parameter you would need to change your controller action to handle it (performing the DB update). – max pleaner Jul 01 '20 at 00:40

1 Answers1

3

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.

rmlockerd
  • 3,776
  • 2
  • 15
  • 25
  • Ok so the link actually goes to something like get '/candidates/:id', to: 'candidates#show'. So in this case I would just place the code you suggested in the show method of the candidates controller? – Wes Creations Jul 01 '20 at 00:56
  • Yes, it would definitely go in the controller that processes the link. My code snippet assumed the link would include the ID of the notification, but it looks like you are linking to the view of a different kind of model. That's not a big deal, but you'll need some way to look up the original Notification, so you might need to also pass its ID as a parameter on the link. – rmlockerd Jul 01 '20 at 01:04
  • OK that makes sense. I'm trying to pass id as parameter to the link like this: <% @a = notify.id %> <% @link = notify.link_path(@a) %> And it's not working. What am I doing wrong here? If I output @a it does in fact give me the id I want. Just not sure how to pass it through link – Wes Creations Jul 01 '20 at 02:30
  • The short answer is to add it to the query string of the URL. Is ``link_path`` a Rails-generated URL helper or what? Let me know and I'll update the answer with info. – rmlockerd Jul 01 '20 at 03:36
  • Yes, link_path is a rails generated URL helper. It's :link_path => national_race_path(@national_race.id)) – Wes Creations Jul 01 '20 at 03:40
  • Yes, that did the trick. Thank you, you are awesome! – Wes Creations Jul 01 '20 at 13:42