I have a WorkSpace model that has_many reviews. In the reviews model I have a rating column using integers for a numbered rating.
I would like to list all of the work_spaces
from a WorkSpace model and also list the top 5 work_spaces
based on the overall review rating of the models.
In my controller I have an index method that works well for retrieving all of the work_spaces.
WorkSpacesControllerclass WorkSpace < ApplicationRecord
belongs_to :user
has_many :reviews, dependent: :delete_all
acts_as_votable
scope :by_average_for, ->(column) {
joins(:reviews)
.group('work_spaces.id')
.order("AVG(reviews.#{column}) desc")
.having("AVG(reviews.#{column}) > 4", column) if column
}
def top_avg_rating
WorkSpace.by_average_for(:rating).limit(5)
end
I have been successful in retrieving the top rated work_spaces by placing my logic in my work_space model.
WorkSpaceclass WorkSpace < ApplicationRecord belongs_to:user has_many:reviews, dependent: :delete_all acts_as_votable scope:by_average_for, ->(column) { joins(:reviews).group('work_spaces.id').order("AVG(reviews.#{column}) desc").having("AVG(reviews.#{column}) > 4", column) if column } def top_avg_rating WorkSpace.by_average_for(:rating).limit(5) end
I send this info out through my serializer and it's easily accessible, but it's attached to every work_space that's indexed. I don't need to have the info attached to each and every work_space. I would ultimately only need to GET this info when the application initially loads.
I figured it would be easy enough to just run a GET request for that info in the WorkSpaces Controller, so I tried adding this method to the controller.
WorkSpacesController def top_rated @work_spaces = WorkSpace.by_average_for(:rating).limit(5) render json: @work_spaces end
I tried to write a new route for it, but I had trouble figuring out how to do that. I tried this in my routes.
get 'top_rated', to: 'work_spaces#top_rated'
with my path being http://localhost:4741/work_spaces/top_rated
This responded with:
Started GET "/work_spaces/top_rated" for::1 at 2020-04-26 23:35:38 -0400 Processing by WorkSpacesController#show as / Parameters: {"id"=>"top_rated"} User Load (0.4ms) SELECT "users".* FROM "users" WHERE "users"."token" = $1 LIMIT $2 [["token", "3bbddce2b4c8f7e6a79a62f56ad9229a"], ["LIMIT", 1]] WorkSpace Load (0.4ms) SELECT "work_spaces".* FROM "work_spaces" WHERE "work_spaces"."id" = $1 LIMIT $2 [["id", 0], ["LIMIT", 1]] [active_model_serializers] Rendered ActiveModel::Serializer::Null with Hash (0.06ms) Completed 404 Not Found in 16ms (Views: 2.6ms | ActiveRecord: 3.1ms)
This seems to me that the parameters are looking for an ID for showing a work_space.
I replaced my original index method with the top_rated method and that worked well, but I can't seem to get both indexes working at the same time.
Should I just leave the logic in the model? I'm wondering what the best practice is for this type of logic. Thanks in advance for any help or guidance you can give me.
Update
I got this to work thanks to NemyaNation .
I changed my route in routes.rb to get '/work_spaces/top_rated' => 'work_spaces#top_rated'
This didn't work until I moved the route above some of my other routes.
# frozen_string_literal: true Rails.application.routes.draw do resources:reviews, except: %i[new edit] get '/work_spaces/top_rated' => 'work_spaces#top_rated' resources:work_spaces, except: %i[new edit] # RESTful routes resources:examples, except: %i[new edit] resources:work_spaces do member do put 'like', to: 'work_spaces#upvote' put 'unlike', to: 'work_spaces#downvote' get 'likes', to: 'work_spaces#like' end end # Custom routes post '/sign-up' => 'users#signup' post '/sign-in' => 'users#signin' delete '/sign-out' => 'users#signout' patch '/change-password' => 'users#changepw' patch '/update-user' => 'users#update' end
Not 100% sure why that is... but using the rake routes
to check my available routes was extremely helpful and led me to hunt down a better understanding of routes.
A couple of links I found helpful:
Your path to the top_rated definition is wrong.
Change your routes.rb to show:
get 'work_spaces/top_rated', to: 'work_spaces#top_rated'
Use the command rake routes
to show you how to properly construct your routes.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.