Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

rails ajax fav button for user posts

I have queried on user posts (nested resources, obviously) and have a long list of posts from different users. I would like the user to be able to click a little star next to each post to favorite that particular post through ajax. Any suggestions on how to achieve this? The trouble I'm running into is multiple favorite buttons on one page, favoriting multiple posts.

This is sorta like Gmail does with favorite emails in their inbox. Actually, it's exactly like that.

like image 464
Lisa Avatar asked Aug 01 '11 13:08

Lisa


2 Answers

First you need to set up the database to handle this, personally I'd go with a has_many :through association because it provides more flexibility over has_and_belongs_to_many. The choice, however, is up to you. I recommend you look up the different types in the API and decide for yourself. This example will deal with has_many :through.

Models

# user.rb (model)
has_many :favorites
has_many :posts, :through => :favorites

# post.rb (model)
has_many :favorites
has_many :users, :through => :favorites

# favorite.rb (model)
belongs_to :user
belongs_to :post

Controller

# favorites_controller.rb
def create
  current_user.favorites.create(:post_id => params[:post_id])
  render :layout => false
end

Routes

match "favorites/:post_id" => "favorites#create", :as => :favorite

jQuery

$(".favorite").click(function() {
  var post_id = $(this).attr('id');
  $.ajax({
    type: "POST",
    url: 'favorites/' + post_id,
    success: function() {
      // change image or something
    }
  })
})

Notes

This assumes a couple of things: Using Rails 3, using jQuery, each favorite icon has an html id with the post id. Keep in mind I've not tested the code and I wrote it in this window so you probably have to fix some minor problems, but it should give you an impression of how I usually does this. The visual stuff and such I'll leave up to you.

If anyone spot any mistakes please feel free to edit this post.

like image 178
amunds Avatar answered Oct 16 '22 09:10

amunds


Do a form_tag for each favorite button with :remote => true. Add the IDs of the post and currently logged in user as hidden fields for each of the forms.

For updating the favorite status you can write a RJS view, which will contain the jQuery to update the favorite to "post has been favorited".

Something like this:

  - for post in @posts
    = form_tag toggle_favorite_post_path, :remote => true
    = hidden_field_tag :post_id, post.id
    = hidden_field_tag :user_id, current_user.id
    - if Favorite.where(:post_id => post.id, :user_id => current_user.id).exists? # TODO: move this to model
      = submit_tag "Add to favorites", :class => "favorite-post-button"
    - else
      = submit_tag "Remove from favorites", :class => "unfavorite-post-button"

You can customize the looks of the submit button(s) to be an image of a star with CSS.

If you want to provide an option to select multiple posts and then favorite them all at once, you'll have to write custom javascript to handle that. On click handler for the "favorite all selected" button, then inside that handler, collect all the post ids which have been selected, serialize the ids into a string and send it back to the controller.

like image 22
randomguy Avatar answered Oct 16 '22 10:10

randomguy