我正在实施属于用户,评论和产品的星级评分系统。我一直在使用教程here。
我在控制台中遇到问题:
xhr.send( ( options.hasContent && options.data ) || null );
当我点击产品/展示页面中的星标时会发生这种情况。页面上没有任何反应,浏览器控制台首先给出了500错误,然后说XHR已完成加载:" POST":
POST http://localhost:3000/ratings/9.json 500 (Internal Server Error) jquery.js?body=1:9632send jquery.js?body=1:9632jQuery.extend.ajax jquery.js?body=1:9177(anonymous function) ratings.js?body=1:26jQuery.event.dispatch jquery.js?body=1:4642elemData.handle jquery.js?body=1:4310
XHR finished loading: POST "http://localhost:3000/ratings/9.json". jquery.js?body=1:9632send jquery.js?body=1:9632jQuery.extend.ajax jquery.js?body=1:9177(anonymous function) ratings.js?body=1:26jQuery.event.dispatch jquery.js?body=1:4642elemData.handle
我不认为这是一个跨域错误,因为我在我的本地环境中运行它。另外,我添加了dataType =' JSONP'对AJAX的调用,它仍然没有工作。这是否意味着失败然后工作?非常困惑。
这是我的Products / show.html.erb页面:
<!--Rating system -->
<% form_id = "product_#{@product.id}_rating" %>
<% if user_signed_in? %> <!-- To avoid throwing an exception if no user is signed in -->
<% user_id = user_signed_in? ? current_user.id : "-1" %>
<% else %>
<% user_id = -1 %>
<% end %>
<h4>Add a rating:</h4>
<%= form_for @product.ratings.find_or_create_by(user_id: user_id), :html => {:id => form_id, :class => "star_rating_form"} do |f| %>
<%= f.hidden_field :product_id, :value => @product.id %>
<% if user_signed_in? %>
<%= f.hidden_field :user_id, :value => current_user.id %>
<% end %>
<%= f.hidden_field :score, :id => form_id + "_stars" %>
<% end %>
<% (1..5).each do |i| %>
<li class="rating_star" id="<%= form_id %>_<%= i %>" data-stars="<%= i %>" data-form-id="<%= form_id %>"></li>
<% end %>
<br><br>
<%= link_to "Back", products_path %> |
<%= link_to 'Edit', edit_product_path(@product) %>
这是ratings.js文件:
$(function() {
$('.rating_star').click(function() {
var star = $(this);
var form_id = star.attr("data-form-id");
var stars = star.attr("data-stars");
function update_stars(){
$('.star_rating_form').each(function() {
var form_id = $(this).attr('id');
set_stars(form_id, $('#' + form_id + '_stars').val());
});
}
function set_stars(form_id, stars) {
for(i = 1; i <= 5; i++){
if(i <= stars){
$('#' + form_id + '_' + i).addClass("on");
} else {
$('#' + form_id + '_' + i).removeClass("on");
}
}
}
$('#' + form_id + '_stars').val(stars);
$.ajax({
type: "post",
url: $('#' + form_id).attr('action') + '.json',
data: $('#' + form_id).serialize(),
success: function(response){
console.log(response);
update_stars();
if(response["avg_rating"]){
$('#average_rating').text(response["avg_rating"]);
}
}
})
});
});
评级控制员:
class RatingsController < ApplicationController
def create
@rating = Rating.new(params[:rating])
@product = Product.find(params[:rating][:product_id])
respond_to do |format|
if @rating.save
format.json { render :json => { :avg_rating => @product.avg_rating } }
else
format.json { render :json => @rating.errors, :status => :unprocessable_entity }
end
end
end
def update
@rating = Rating.find(params[:id])
@product = Product.find(params[:rating][:product_id])
@comment = @rating.comment
@rating.update_attributes(params[:rating])
respond_to do |format|
if @rating.save
format.json { render :json => { :avg_rating => @product.avg_rating } }
else
format.json { render :json => @rating.errors, :status => :unprocessable_entity }
end
end
end
def rating_params
params.require(:rating).permit(:score)
end
end
评级模型:
class Rating < ActiveRecord::Base
belongs_to :comment
belongs_to :user
belongs_to :product
end
产品型号:
class Product < ActiveRecord::Base
belongs_to :user
has_many :comments, dependent: :destroy
has_many :ratings
validates :title, presence: true,
length: { minimum: 5, maxmimum: 140 }
validates :price, presence: true
validates :description, presence: true,
length: { minimum: 5 }
def avg_rating
average_rating = 0.0
count = 0
ratings.each do |rating|
average_rating += rating.score
count += 1
end
if count != 0
(average_rating / count)
else
count
end
end
end
最后,评级星的css(只有一张图片包含一个填充星和空星,取自上面引用的教程。
li.rating_star {
float:left;
list-style: none;
margin: 0;
padding: 0;
width: 25px;
height: 25px;
background: asset-url('star.png', image) top left;
}
li.rating_star.on {
background: asset-url('star.png', image) 0 -25px;
}
感谢大家提前帮助。