Home > OS >  URL Structure for Comparing Items
URL Structure for Comparing Items

Time:09-17

What is the best way to structure a route for comparing multiple items?

Here's the URL example: https://versus.com/en/microsoft-teams-vs-slack-vs-somalia

How to achieve this in routes.rb file? Cannot really find anything in Internet regarding ruby gems. The only thing I can think about is url with optional params, however what if the number of params is unlimited?

CodePudding user response:

you're going to have to parse the a-vs-b-vs-c yourself.

So in routes.rb, you'll have something like:

get 'compare/:compare_string', to 'compare#show'

then you'll get a parameter compare_string that you'll have to parse:

#in compare_controller.rb

def show
  compare_items = params[:compare_string].split('-vs-')

  # generate the comparison from the compare_items array
end

CodePudding user response:

First - you probably shouldn't allow unlimited #'s of parameters in practice. Even something like 100 might break your page and/or cause performance issues and open you up to DOS attacks. I'd choose some kind of sensible/practical limit and document/enforce it (like 10, 12 or whatever makes sense for your application). At around 2k characters you'll start running into URL-length issues.

Next - is there any flexibility in the URL? Names tend to change so if you want URL's to work over time you'll need to slug-ify each of them (with something like friendly-id) so you can track changes over time. For example - could you use an immutable/unique ID AND human-readable names?

In any case, Rails provides a very flexible system for URL routing. You can read more about the various options / configurations with their Rails routing documentation.

By default a Dynamic Segment supports text like in your example, so (depending on your controller name) you can do something like:

get 'en/:items', to: 'items#compare'

If it's helpful you can add a custom constraint regexp to guarantee that the parameter looks like what you expect (e.g. word-with-dashes-vs-another-vs-something-else)

get 'en/:items', to: 'items#compare', constraints: { items: /(?:(?:[A-Z-] )vs) (?:[A-Z-] )/ }

Then, in your controller, you can parse out the separate strings however you want. Something like...

  def compare
    items = params[:items].split('-vs-')
  end
  • Related