Reputation: 387
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
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