3

When the notifications button is clicked it sends a get request to controller which is supposed to update the Activity.viewed to true from false. This way my js knows not to populate it back into the notifications count. So:

I have an ajax GET request

  // click EVENT TRIGGERS
  $('#bell-notices').click(function(){
    var $bell = $(this);
    $bell.find('.notifications-count').hide('0');
    $bell.parent().find('.dropdown-toggle').dropdown();
    $.get('/activities/mark_activity_viewed', function( data ) {
    });
  });

being sent to rails controller

  def mark_as_viewed    
    @mark = Activity.find_by(params[:id])
    @mark.viewed = true
    @mark.save!
  end

everything is in place properly it seems, yet I can't get the database to update.

Console for Activity.last

<Activity id: 190, user_id: 68, action: "created", targetable_id: 157, targetable_type: "Status", created_at: "2015-03-04 21:17:57", updated_at: "2015-03-04 21:17:57", commentable_id: nil, reference_id: nil, viewed: false> 

user_id in this case is the user who created the activity, not the user that's receiving it.

7
  • There is no data being sent in your $.get. Also no idea where id would come from to be able to send it. Show some html source code Commented Mar 4, 2015 at 20:26
  • @charlietfl, Once the user clicks the notifications button I just need it to mark all of the users activity as viewed. So my thinking was that it would just search for all activity for that user that currently has the field viewed == false and update it to = true for the Activity model. So no activity should need to be passed in from the GET request. If that makes sense? Commented Mar 4, 2015 at 20:46
  • Suggest you update question with that part. If request is being made ( check network tab of browser console) then issue is rails and I know little about rails Commented Mar 4, 2015 at 20:49
  • You should really be using a 'put', not a 'get', and doing this update preferably through the User model. If you're going to update all activities for the current user, you need to reference that user somehow. If you're using devise, then you would call current_user in your controller. If you're storing it in a session variable yourself, then you'd get it from there. How are you keeping track of current user? Commented Mar 4, 2015 at 20:54
  • @JPlato, using devise. So you're saying pass in current_user in the controller then create a method in the User.rb, not in the Activity.rb? Commented Mar 4, 2015 at 21:02

1 Answer 1

3

Don't use $.get() to make calls that update data. Send the request via PUT instead. Since you're updating all of the user's activity, you don't need to do an Activity.find lookup. I'm assuming your User model has a 'has_many :activities' association defined. Your JS would look like this (I'm using coffeescript):

$('#bell-notices').click ->
  $bell = $(this)
  $bell.find('.notifications-count').hide '0'
  $bell.parent().find('.dropdown-toggle').dropdown()
  $.ajax 
      url: '/activities/mark_activity_viewed'
      type: 'put'

(as JS):

$('#bell-notices').click(function() {
  var $bell;
  $bell = $(this);
  $bell.find('.notifications-count').hide('0');
  $bell.parent().find('.dropdown-toggle').dropdown();
  $.ajax({
    url: '/activities/mark_activity_viewed',
    type: 'put'
  });
});

In your activities_controller, you would have:

def mark_activity_viewed    
    current_user.activities.update_all(viewed: true)
    [any respond_to stuff you care to do...]
end

You need to have a route in routes.rb that matches the 'put'

put 'activities/mark_activity_viewed' => 'activities#mark_activity_viewed'

Note that the 'update_all' above will skip validations on Activity, but since all you're doing here is changing a boolean value, this shouldn't be an issue. If you want validations on each Activity to be performed, loop through them and do the typical update and save!

Which controller you put this in is really up to you. I would put it in the users_controller, since it is a more user-centric action, but there's nothing wrong with leaving it in the activities controller.

Sign up to request clarification or add additional context in comments.

7 Comments

And if I chose to pass in and update just the values for which ID's haven't been read and have var in the js with those already, what would that look like. I currently have a var viewed_event_ids = []; that populates with all Activity id's of activity wiih viewed == false. I feel that may be a better route.
Aren't the not-yet-read activities already flagged as such in the activities table? Or do you mean that, at the interface, the user may read some activities and not others, and you keep track of that on the client side?
Once opened, I would mark all activity as viewed, which would equate to all the activity belonging to that user as being viewed. So I guess the current setup is sufficient. But for some reason that $.ajax request isn't sending anything in the console. Nothing happens on .click
If you think it's going to update too many records, you can always do: current_user.activities.where(viewed: false).update_all(viewed: true). As for the click not working, are you sure you've got the selector right? Try putting "alert('click');" or "console.log('click');" in your click handler to see if it's getting invoked at all. Also, remember that the code I posted is coffeescript. If you're using straight-up JS, make sure you convert it.
The problem you're having with the 'put' is that you entered it in your routes.rb file after your call to 'resources :activities', and Rails is trying to route it to the activities_controller 'update' method. Rails will use the first matching route it finds, so to fix this, just move your 'put' route above 'resource:activities' in your file, and it should work. I strongly recommend against using GET for requests that update the DB. See the Rails Guide on security for more info on this.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.