views:

11

answers:

1

I am implementing a "favorites" feature into a community blog application, and would like to use Ajax.

When users like a front page post, there is a "+" symbol they can click to add that post to their collection of favorites.

The feature works great without Ajax functionality. But now I'm adding the Ajax.

In the view:

<span id="favorite_<%= entry.id %>">
  <%= link_to_remote "+",  :url => { :action => 'add_favorite' },
                           :entry => entry.id,
                           :user => session[:user_id],
                           :update => 'favorite_' + entry.id.to_s %>
</span>

The corresponding controller action:

def add_favorite
  @favorite = Favorite.new(:entry_id => :entry, :user_id => :user)
  if @favorite.save
    render :text => "added to favorites", :layout => false
  end
end

The text is rendering appropriately in the view, as though the action has worked. But when I check the list of favorites, it hasn't been added.

I ran the line

@favorite = Favorite.new(:entry_id => :entry, :user_id => :user)

in the interactive shell and it was all good. Everything saved.

What am I overlooking/doing wrong?

A: 

For some reason you're passing in symbols instead of variables, so you're probably getting a record with nothing assigned, and hence no association:

@favorite = Favorite.new(:entry_id => params[:entry_id], :user_id => params[:user_id])

That should handle linking the associations if you have a belongs_to defined.

Keep in mind that :user_id is merely a symbol, nothing more, where user_id is a variable, and params[:user_id] is the parameter that may have been passed in. Symbols are often used as hash keys because they are very light-weight and easy to compare.

For consistency's sake, try and pass in _id type parameters with the _id at the end. In this case this would be:

<%= link_to_remote "+",
     :url => { :action => 'add_favorite' },
     :entry_id => entry.id,
     :user_id => session[:user_id],
     :update => 'favorite_' + entry.id.to_s
%>
tadman
Thanks tadman! The other half of the solution was to include :entry_id and :user_id as part of the url ( :url => { in here } ).
Trev
You're right on that count, too. Don't forget that many models may have a custom `#to_param` method that you should use in place of `#id`. The only place where using `#id` is appropriate is as a unique identifier, like for your DOM ID, or when constructing SQL. For URLs, always use `#to_param`.
tadman