简体   繁体   中英

What is the best way to GET two index requests from the same model in RoR?

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.

WorkSpacesController
class 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.

WorkSpace
class 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:

https://guides.rubyonrails.org/routing.html

https://devhints.io/rails-routes

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM