Ajaxified Star Rating System is not Updating Corre

2019-04-15 00:02发布

问题:

I've implemented a Star Rating System using this tutorial http://eighty-b.tumblr.com/post/1569674815/creating-an-ajaxified-star-rating-system-in-rails-3

The Ajax works perfectly, until I add the Javascript that Submits the form/saves the data after a given user makes a change.

For some reason, it will loop through all the elements on my Index Page, and Submits the correct integer value on the selected object, but then submits a bunch of NIL values on the rest. I only want it to update that ONE object.

(How can I submit the appropriate Book ID in the Javascript?)

New to rails please help :)

VIEWS

index.hrml.erb (books)

  <% @books.each do |book| %>
    <table id="book<%= book.id %>">
      <tbody>  
        <tr>  
          <td>
            <b><%= book.title %></b>
          </td> 
        </tr> 
        <tr>
          <td>  
            <%= book.release %>
          </td>
        </tr>
        <tr>

          <td  id="rating">     #####This is my partial for my form                 
            <%= render :partial => 'ratings/rating', :locals =>{:book => book} %>
          </td>

        </tr>
      <tbody>
    </table>
  <% end %>

_rating.html.erb

  Avg. Rating <%= book.average_rating %>

<%= form_for rating_ballot, :html => { :class => 'rating_ballot' }, :remote => true do |f| %>
<%= render 'shared/error_messages', object: f.object %>

   <%= f.label("value_1", content_tag(:span, '1'), {:class=>"rating", :id=>"1"}) %>
   <%= radio_button_tag("rating[value]", 1, current_user_rating == 1, :class => 'rating_button') %>

   <%= f.label("value_2", content_tag(:span, '2'), {:class=>"rating", :id=>"2"}) %>
   <%= radio_button_tag("rating[value]", 2, current_user_rating == 2, :class => 'rating_button') %>

   <%= f.label("value_3", content_tag(:span, '3'), {:class=>"rating", :id=>"3"}) %>
   <%= radio_button_tag("rating[value]", 3, current_user_rating == 3, :class => 'rating_button') %>

   <%= f.label("value_4", content_tag(:span, '4'), {:class=>"rating", :id=>"4"}) %>
   <%= radio_button_tag("rating[value]", 4, current_user_rating == 4, :class => 'rating_button') %>

   <%= f.label("value_5", content_tag(:span, '5'), {:class=>"rating", :id=>"5"}) %>
   <%= radio_button_tag("rating[value]", 5, current_user_rating == 5, :class => 'rating_button') %>

   <%= hidden_field_tag("book_id", book.id) %>
   <%= f.submit "Submit", class: "btn btn-primary"%>

<% end %>

create.js.erb & update.js.erb

$('table#book<%= @book.id%> td#rating').html("<%= escape_javascript(render :partial => 'ratings/rating', :locals => {:book => @book}) %>");

JAVASCRIPT

rating_ballot.js

####This Submits the Radio Button, but Loops through every Book on the page. 

$(document).ready(function() {

    ###Submits the form (saves data) after user makes a change.

    $('.rating_ballot').change(function() {
    $('.rating_ballot').submit();
  });
});

CONTROLLER

class RatingsController < ApplicationController
  before_filter :current_user, only: [:create, :update]

  respond_to :html, :js

  def create
    @book = Book.find_by_id(params[:book_id])
    @rating = Rating.create(params[:rating])    
    @rating.book_id = @book.id
    @rating.user_id = current_user.id
    if @rating.save
      respond_to do |format|
        format.js
        format.html { redirect_to :back }
      end
    end
  end

  def update
    @book = Book.find_by_id(params[:book_id])
    @rating = current_user.ratings.find_by_book_id(@book_id)
    if @rating.update_attributes(params[:rating])
      respond_to do |format|
        format.js
        format.html { redirect_to :back }
      end
    end
  end

end

回答1:

This is bcoz all the rating forms are submitted whenever any single rating is changed Change your JS code as follows

$(document).ready(function() {
  $('.rating_button').change(function() {
    $(this).parents('form:first').submit();
  });
});

Also above code will not work in JS loaded content. i.e. your rating form will not be submitted once you add rating and that form is updated from create.js.erb or update.js.erb

Change it to

$(document).ready(function() {
  $(document).on('change', '.rating_button', function(){
    $(this).parents('form:first').submit();
  });
});