I have queried on user posts (nested resources, obviously) and have a long list o开发者_StackOverflowf 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.
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.
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.
精彩评论