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:so presumably you have the
params[:id]
that your helper depends on. But why would you expectparams[:id]
to be anything other thannil
when you get to your partial throughindex
? You have accidentally coupled your helpers to yourshow
controller by making bad assumptions about what is inparams
.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:
and then in your partial you can say:
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 localrating
variable instead.