Search code examples
ruby-on-railsrubyrating

Rails user rating, can only rate myself


I am trying to set up a 5 star rating system so users can rate other users. At the moment everything is working, (create, delete, update etc...) but only the logged in user can rate himself. I cannot rate other users. I get no errors, it just redirects to the user profile page as it should but without added a rating to that user.

user.rb

class User < ActiveRecord::Base
has_many :reviews

review.rb

class Review < ActiveRecord::Base
  belongs_to :user
end

reviews_controller.rb

class ReviewsController < ApplicationController

 before_action :find_user
 before_action :find_review, only: [:edit, :update, :destroy]

 def new
   @review = Review.new
 end

 def create
   @review = Review.new(review_params)
   @review.user_id = current_user.id
   if @review.save
     redirect_to user_path(@user)
   else
     render 'new'
   end
 end

 def edit
 end

 def update
   if @review.update(review_params)
     redirect_to user_path(@user)
   else
     render 'edit'
   end
 end

 def destroy
   @review.destroy
   redirect_to user_path(@user)
 end

 private

 def review_params
   params.require(:review).permit(:rating, :comment)
 end

 def find_user
   @user = User.find(params[:user_id])
 end

 def find_review
   @review = Review.find(params[:id])
 end

end

_form which then gets rendered on show page:

<%= simple_form_for([@user, @user.reviews.build]) do |f| %>
  <div id="rating-form">
    <label>Rating</label>
  </div>
  <%= f.input :comment %>
  <%= f.button :submit %>

<% end %>

<script>
  $('#rating-form').raty({
    path: '/assets/',
    scoreName: 'review[rating]'
  });
</script>

Any help getting this to work would be greatly appreciated!!


Solution

  • Do this:

    #config/routes.rb
    resources :users do
       resources :reviews, only: [:new, :create]
    end
    
    
    #app/models/review.rb
    class Review < ActiveRecord::Base
       belongs_to :user
       belongs_to :reviewed, class_name: "User", foreign_key: :reviewed_id
    end
    
    #app/controllers/reviews_controller.rb
    class ReviewsController < ApplicationController
       def new
          @review = current_user.reviews.new
       end
    
       def create
          @review = current_user.reviews.new review_params
          @review.save
       end
    
       private
    
       def review_params
          params.require(:review).permit(:rating, :comment).merge(reviewed_id: params[:user_id])
       end
    end
    
    #app/views/reviews/new.html.erb
    <%= form_for @review do |f| %>
        <%= f.number_field :rating %>
        <%= f.text_field :comment %>
        <%= f.submit %>
    <% end %>
    

    This would mean you'll have to include a reviewed_id column in your reviews table.

    You'll be able to access it using: url.com/users/:user_id/reviews/new

    The application will automatically fill the user_id and reviewed_id fields, so the rest of your code should work with the upgrade.

    The big problem you have is that you're basically recording the user_id (presumably of who created the review)... but have no way of stipulating who the review is about.

    The above code fixes that for you.