Seph Cordovano
Seph Cordovano

Reputation: 2054

Update DB with ajax request in rails

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.

Upvotes: 3

Views: 2315

Answers (1)

J Plato
J Plato

Reputation: 898

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.

Upvotes: 3

Related Questions