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 and so do my methods on the BOOKS SHOW PAGE
But for some reason, my Helper Methods do not work on the Index Page where I list multiple Books, therefore I am unable to call the current_user_rating on my Index Page.
it just doesn't show up, like on the show page it shows the integer or current user value, and on the index page. its just displays "N/A" even when it contains a value.
I have tried different things but can't seem to make it work...
Let me know if you need me to add anything else
New to rails please help :)
HELPERS
module BooksHelper
##The first part of each Methods work on Show Page but Not Index
def rating_ballot
if @rating = current_user.ratings.find_by_book_id(params[:id]) ****
@rating
else
current_user.ratings.new
end
end
def current_user_rating
if @rating = current_user.ratings.find_by_book_id(params[:id]) ****
@rating.value
else
"N/A"
end
end
end
VIEWS
show.html (books)
<div id="book<%= @book.id %>">
<div id="rating">
<%= render :partial => 'ratings/rating', :locals =>{:book => @book} %>
</div>
</div>
index.html.erb (books)
<% @books.each do |book| %>
<table id="book<%= book.id %>">
<tbody>
<tr>
<td>
<%= book.title %>
</td>
</tr>
<tr>
<td id="rating">
<%= render :partial => 'ratings/rating', :locals =>{:book => book} %>
</td>
</tr>
<tbody>
</table>
<% end %>
_rating.html.erb (ratings)
###This Doesn't work in my INDEX PAGE :/
Your Rating <%= current_user_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("issue_id", issue.id) %>
<%= f.submit :Submit, :style => "display:none" %>
<% end %>
MODEL
class User < ActiveRecord::Base
attr_accessible :name, :email,
has_many :ratings, dependent: :destroy
has_many :rated_books, :through => :ratings, :source => :books
end
class Rating < ActiveRecord::Base
attr_accessible :book_id, :user_id, :value
belongs_to :user
belongs_to :book
end
class Book < ActiveRecord::Base
attr_accessible :description, :title
has_many :ratings
has_many :raters, :through => :ratings, :source => :users
end
CONTROLLER
class BooksController < ApplicationController
respond_to :html, :js
def show
@book = Book.find(params[:id])
end
def index
@books = Book.all(:include => :ratings, :order => "book_number")
end
end
When you go through show
, you have this:
@book = Book.find(params[:id])
so presumably you have the params[:id]
that your helper depends on. But why would you expect params[:id]
to be anything other than nil
when you get to your partial through index
? You have accidentally coupled your helpers to your show
controller by making bad assumptions about what is in params
.
My advice is to (almost) never access params
in a helper method, you'll have clearer and more maintainable (let alone less buggy) code if you pass the helper as much information as possible through its arguments.
Your helpers should look more like this:
def rating_ballot(book_id)
if @rating = current_user.ratings.find_by_book_id(book_id)
#...
def current_user_rating(book_id)
if @rating = current_user.ratings.find_by_book_id(book_id)
#...
and then in your partial you can say:
Your Rating <%= current_user_rating(book.id) %>
I'd also recommend that you don't use @rating
inside your helpers, that just pollutes your namespace with stray instance variables (that don't even have a clear connection to where they came from), just use a local rating
variable instead.