In my app, users have the ability to favorite items (“listings”). To make it a smooth user experience, I’m handling the favoriting through ajax. The only problem is that the ajax isn’t rendering correctly.
The html.erb related to the favorite button is the following:
Upon the successful create action, the above javascript is run. The intended effect is that the “Save to Favorite” button is replaced by the “Remove as Favorite” code. The only problem is that the rendered via javascript code doesn’t link to the proper link and not surprisingly doesn’t work. Upon page load, the favorite path works and links to “/favorites?=id=33333”. After clicking the favorite button, the button no longer correctly removes the item as a favorite and it appears to fail because the url is not correct.
There are a couple of things I notice. The first is that in the javascript selector you use an instance variable @listing and then in the link_to you use a local variable, listing. I’m guessing you want the instance variable.
Next, instead of listing_path(:id=> listing.id) please try listing_path(@listing)
Finally, this isn’t your problem, but there is a view helper you can use that will output the listing_<%= @listing.id %> for you. it is dom_id you can read more about it here. So using this method you would do
$("#<%= dom_id(@listing) %> .favorite-btn")
I hope that helps, let me know how it works out and if you have any further trouble with this.
The reason that I was using @listing in one place and just listing in another is that the favorite_button html was extracted into a view partial ( render "favorite_button", listing: @listing).
I’m a little hung up on modifying the params. It works fine for the destroy method because the natural Rails route for a delete action is /favorites/:id(.:format), which expects an id to be passed in the params. With the create action, the natural Rails route is /favorites(.:format). As a result, I was passing the id as I was as id: listing.id
Maybe this has to do with how I setup the models/controllers? In the create action,
def create
@listing = Listing.find(params[:id])
if current_user.user_favorite_listings << @listing
.....
end
It looks like Chad’s suggestion on modifying the delete path was the right solution and it now works as expected.
My only remaining question on this is whether the way I am passing the id params through the create action is the proper way to handle this case. Thanks everyone!