0

I have a method that sorts the index for a list of products. Sorts them alphabetically, by rating, etc. That works perfect.

When I got to the show page, I added next and previous buttons. But they are working off the next ID in the table, not the next in the sort I made. I think as a user, I want to cycle through my currently chosen sort.

So I changed the next/previous methods to get the index of the current show product, next will add +1, previous -1 to the index and check the length -1 to start it back to zero.

But here's the issue. I need to preserve the current variable of the sort for the next/previous methods to access.

The approach I'm trying: I think I need to use after_action on the controller to set the variable aside in a method. The index method contains the used sort variable something like:

after_action :set_product_sort, only: [:index]

  private
    def set_product_sort
      @current_product_sort = @products_sort
    end

From research, I keep seeing i have to involve the routes. Something like this:

  resources :products_controller do
    collection do
      get :set_product_sort
    end
  end

So if that makes sense (I'm out of my depth here). I am not clear on a few things.

If I do before_action on the index method, the variable will not be set to the sort. So I think after_action is what I need. But am I wrong? Will the variable already be dropped at that point?

In that routes block, what is "collection". I got that block from a blog post and trying to look up "collection" yields general info about collections. I am thinking perhaps collection is supposed to be the variable name (ie @products_sort)?

And finally, how would I call upon this next/previous Next/previous need to know the current product as well as the current sort. The current product is already in the controller show method. Does that routes.rb block set the sort variable up to just call it in method? or does it need to be dot notation and maybe make the next/previous self.next and self.previous?

9
  • I was mistaken when I said "model" for that 2nd block. I edited to say "routes.rb". Sorry Commented Apr 30, 2021 at 16:27
  • 1
    The main issue is that the server is stateless and all info needed to parse a request should be send by the client. In this scenario you probably want to sent a page number through the request parameters. eg. use the path products_path(page: 2) -> /products?page=2 Then in your index compute the offset based of the page. Product.where(...).order(...).offset(params[:page].to_i * 20) (0 based page number, 20 records per page). There are a some gems out there that simplify pagination. Commented Apr 30, 2021 at 16:35
  • I think the routes part is because the block I saw was from a question about preserving an API call. So not my use case. Commented Apr 30, 2021 at 16:35
  • 3limin4t0r - That makes sense. And I am using the will-paginate gem. However that is on the index page itself. In this case, I've clicked on the link for one of the indexed products and I'm now on the show page. I want to got back and forth from there. Commented Apr 30, 2021 at 16:39
  • Ah, I understood the question wrong. You want to cycle though records records from the show page based upon the ordering from the index page. That makes things more difficult. Commented Apr 30, 2021 at 16:59

1 Answer 1

1

I'm guessing this is a pure Rails app? I would suggest using a different route for each of your sorted index pages, or maybe using nested routes. That way you could do localhost:3000/products/alpha/:id or localhost:3000/products/by_rating/:id, etc. That way the server can parse the request based on the URL and send the appropriate record.

Your routes would look something like:

get '/products/alpha/:id/', to: 'products#show_alpha', as: 'product_alpha_show'
get '/products/by_rating/:id', to: 'products#show_by_rating', as: 'product_rating_show'

Or something along those lines.

If you don't want different URL paths for the different index pages then I think you're looking at storing the sort method in localStorage, or some sort of token.

Fairly new to programming myself, but that's what I would do.

Sign up to request clarification or add additional context in comments.

4 Comments

Thank you! That makes sense! I really went crazy with sorts. I am sorting product lists about 8 different ways. Same amount for listing product reviews. 6 ways to sort the users own reviews. About 6 to sorry a total list of reviewers. And on the product ID show page (where the next/previous buttons live) I have a list of all that products reviews sortable in about 6 ways. That’s a lot of routes! Given that amount of routes, would you still take approach? I wonder if I would be creating new problems I’m not aware of.
And yes, rails 5.2
Another idea: you could create one path using dynamic route segments. Something like get '/products/:sort/:id', to: 'products#sorted_show', as: 'sorted_show'. Then your sorted_show method in the ProductsController can use a case statement to check params[:sort] to return the appropriate record. The same thing could be done for your custom sorted indices. That way you could have one controller method for your custom sorts and show pages, and just parse using the dynamic segment of the URL.
That sounds perfect! I'll take a stab at it. Thank you!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.