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