2014-10-31 4 views
1

등급 시스템을 구현하려고합니다.TypeError (Float에 강제로 입력 할 수 없음) :

Started PATCH "/ratings/7.json" for 127.0.0.1 at 2014-10-31 14:09:58 +0200 
Processing by RatingsController#update as JSON 
    Parameters: {"utf8"=>"✓", "authenticity_token"=>"j/bCg3mFtQLl1n5qSZInNrUoKaRT/PKpzLnEz6QNGcQ=", "rating"=>{"book_id"=>"1", "user_id"=>"1", "stars"=>"4"}, "id"=>"7"} 
    User Load (0.4ms) SELECT "users".* FROM "users" WHERE "users"."id" = 1 ORDER BY "users"."id" ASC LIMIT 1 
    Rating Load (0.2ms) SELECT "ratings".* FROM "ratings" WHERE "ratings"."id" = $1 LIMIT 1 [["id", 7]] 
    (0.1ms) BEGIN 
    (0.2ms) COMMIT 
    Book Load (0.2ms) SELECT "books".* FROM "books" WHERE "books"."id" = $1 LIMIT 1 [["id", 1]] 
    Rating Load (0.3ms) SELECT "ratings".* FROM "ratings" WHERE "ratings"."book_id" = $1 [["book_id", 1]] 
Completed 500 Internal Server Error in 8ms 

TypeError (nil can't be coerced into Float): 
    app/models/book.rb:30:in `+' 
    app/models/book.rb:30:in `block in avg_rating' 
    app/models/book.rb:29:in `avg_rating' 
    app/controllers/ratings_controller.rb:37:in `block (2 levels) in update' 
    app/controllers/ratings_controller.rb:35:in `update' 

내 show.html.erb보기 :

<% form_id = "book_#{@book.id}_rating" %> 
<% if user_signed_in? %> <!-- To avoid throwing an exception if no user is signed in --> 
    <% user_id = current_user.id %> 
<% else %> 
    <% user_id = -1 %> 
<% end %> 
<%= form_for @book.ratings.find_or_create_by(user_id: user_id), :html => {:id => form_id, :class => "star_rating_form"} do |f| %> 
    <%= f.hidden_field :book_id, :value => @book.id %> 
    <% if user_signed_in? %> 
     <%= f.hidden_field :user_id, :value => current_user.id %> 
    <% end %> 
    <%= f.hidden_field :stars, :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 %> 

내 ratings_controller.rb :

내가 등급을 부여하려고 할 때이 오류가 계속 this tutorial

을 통해가는

before_filter :js_logged_in 

    def create 
    @rating = Rating.new(rating_params) 
    @book = Book.find(params[:rating][:book_id]) 

    respond_to do |format| 
     if @rating.save 
     format.json { render :json => { :avg_rating => @book.avg_rating } } 
     else 
     format.json { render :json => @rating.errors, :status => :unprocessable_entity } 
     end 
    end 
    end 

    def update 
    @rating = Rating.find(params[:id]) 

    respond_to do |format| 
     if @rating.update_attributes(rating_params) 
     format.json { render :json => { :avg_rating => @rating.book.avg_rating } } 
     else 
     format.json { render :json => @rating.errors, :status => :unprocessable_entity } 
     end 
    end 
    end 


    def js_logged_in 
    if(!user_signed_in?) 
     flash[:error] = "You must be a signed in to leave a rating!" 
     render :js => "window.location = '/users/sign_in'" 
    end 
    end 

    private 

    def rating_params 

    params.require(:rating).permit(:book_id, :stars, :user_id) 

    end 

My book.rb 모델 :

내 rating.rb 모델 :

class Rating < ActiveRecord::Base 
    belongs_to :book 
    belongs_to :user 
    attr_accessor :stars 
end 

사람이 단서가 - 왜이 작동하지 않습니다?

+0

귀하의 모델에서'rating.stars'가'nil'이 아닌지 확인해야합니다. 'rating.stars'가'rating' 배열에있는 객체 중 하나에 대해 nil이므로이 오류가 발생합니다. 문제를 극복하기 위해서'average_rating + = rating.stars.to_f'와 같은 것을 할 수 있습니다. 이렇게하면'nil'을'0.0'으로 변환하여 코드가 손상되지 않고 문제를 해결할 수 있습니다. –

답변

0

등급 'stars'중 하나 이상이 nil을 반환합니다. 따라서 average_rating += rating.stars (average_rating = average_rating + nil과 동일)으로 전화하면 오류가 발생합니다. 이 분야에서 nil 값이 0을 의미하는 경우, 당신은 아마이 있어야합니다 nil 값이이 분야에서 바람직하지 않다

average_rating += rating.stars || 0 

경우 Rating 모델을 확인해야합니다 :

validates_presence_of :stars 

또한, stars이기 때문에 ratings 테이블의 필드에 attr_accessor :starsRating 모델에 필요하지 않습니다.

+0

글쎄,이 오류가 발생하지 않습니다. 그러나 DB에 기록 된 등급은 0 등급입니다. –

+0

@AndreiCirnici 모든 평가 에서요? 'Rating.where (stars : nil) .count'는 무엇을 반환합니까? –

+0

2.1.3 : 053> Rating.where (별표 없음) .count (69.5ms) "등급"에서 "별점"의 수를 선택하십시오. "별"은 NULL입니다. => 0 –

관련 문제