Rails: replace "create" form with "edit" form after ajax request
So, here's my problem:
I have a Rails 3 app with Photos and Users. Users have_many photos. Photos can be voted "thumbs up" or "thumbs down" by other users. There is a Vote model that handles this. Users have many votes (one per photo) and photos have many votes (one per user), in a two-way has_many :through relationship.
To allow the thumbs-up / thumbs-down voting I have a form that is submitted via ajax. The form functions just fine, however I've run into a problem I don't really understand.
When a user visits a photo for the first time the user has not yet voted either thumbs up or thumbs down, so there is no "vote" object for this user for this photo. Therefore the form partial that allows the user to vote is going to send a "create" request.
This request is handled by ajax. It works correctly, and the stats for the photo update (via ajax) as the vote is cast.
Users can also change their votes. If a user visits a photo that they have voted on before they see the form to edit their vote. They can change their vote as many times as they want, and the page updates just as expected via ajax.
The problem is this:
After the FIRST time a user votes, t开发者_如何学Gohe form needs to be updated so that it is no longer trying to create a NEW vote, but edit the existing, just-created vote. This currently does not work.
If a user votes for the first time, then changes his mind, the form will not respond because it is still set in the HTML to send a "create" request, and the model does not allow a user to create more than one vote per photo.
So the problem is, the ajax request from the form needs to update the form, not just the photo stats.
The code I have for my "create.js.erb" is as follows:
$(function () {
$('table#content_score').replaceWith("<%= escape_javascript(render :partial => 'stats') %>");
$('form.vote_ballot').replaceWith("<%= escape_javascript(render :partial => 'ballot') %>");
});
What should happen is the vote_ballot form is refreshed - hence changing from "new" to "edit". This DOES happen if you refresh the page, but not if you create a new vote via AJAX. However, the initial click does refresh the stats (the first line, replacing 'table#content_score').
So, any ideas or suggestions?
How do you get a form to change from "new" to "edit" when creating content using ajax? What am I missing?
Thanks!
Instead of trying to change the DOM in complicated ways, why not make one action either create or update a vote. Having only one vote per photo is domain logic, so it would make sense to put it in the model.
class Vote < ActiveRecord::Base
def self.vote(user, photo_id, attributes = {})
vote = user.votes.find_or_create_by_photo_id(photo_id)
vote.update_attributes!(attributes)
vote
end
end
Don't worry about seeming to break the REST convention for this one. From the users point of view, you are voting, the identity of the vote you might have given before has nothing to do with it.
精彩评论