Ruby on Rails: Can't implement Star Rating sys

2019-04-16 12:59发布

问题:

I'm trying to add a simple Star Rating system for my app having taken this tutorial for an example. I have User, Hotel and Rating models. Dependencies are:

(rating.rb)

  belongs_to :user
  belongs_to :hotel  

(hotel.rb) & (user.rb)

has_many :ratings

And with the following code in hotel view I get this error:

NameError in Hotels#show

undefined local variable or method `user' for Class...

(in the line with <%= form_for...)

Hotel view (show.html.erb):

      <% form_id = "hotel_#{@hotel.id}_rating" %>
      <% if 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 @hotel.ratings.find_or_create_by_user_id user.id, 
                      :html => {:id => form_id, 
                      :class => "star_rating_form"} do |f| %>
              <%= f.hidden_field :hotel_id, :value => @hotel.id %>
              <% if 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 is:

def create
end

def update
end

def rating_params
  params.require(:rating).permit(:stars)
end

Migration file is:

create_table :ratings do |t|
  t.integer :stars, :default => 0
  t.references :store
  t.references :user
end

回答1:

From the comments, the error seems to be here:

@hotel.ratings.find_or_create_by_user_id user.id

--

user_id

The problem is your show view doesn't have access to a local variable called user

This variable should either be defined in the controller (which would mean it has to be an @instance variable, or should be a helper (such as current_user.id)

The fix should therefore be as follows:

<% user_id = user_signed_in? ? current_user.id : "-1" %>

<%= form_for @hotel.ratings.find_or_create_by_user_id user_id ...

This should get it working for you with the code you have provided. As you've not provided the new action from the controller, I don't know whether the supporting structure for the code will be correct or not.



回答2:

After some search on find_or_create_by, I changed line with 'form_for' into

<%= form_for @hotel.ratings.find_or_create_by(user_id: user_id)

That solved the issue!

Thanks to all for your support!