smeeb
smeeb

Reputation: 29517

How to validate path params and explicitly set status codes in Rails

I am trying to set up a super simple RESTful endpoint (as an ApplicationController) that does simple path param validation and that returns a hardcoded JSON response:

{
  "foo" : "123",
  "bar" : {
    "whistle" : "feather",
    "ping" : "pong"
  }
}

The URL being hit is GET http://localhost/widgets/${widgetId}/${fizzbuzzId} where both ${widgetId} and ${fizzbuzz} are expected to be positive integers.

I'm trying to figure out how to check the value of ${widgetId} and ${fizzbuzzId} and throw a 400 if they aren't positive integers. I'm also trying to figure out how to return the hardcoded response string as the HTTP response entity with status code 200 if the two path params survive validation:

In the routes.rb:

resource :widgets

And then the controller:

class WidgetsController < ApplicationController
  def show
    if(params[:widgetId].to_i <= 0 || params[:fizzbuzzId] <= 0) {
      render json: { "error" : "bad path params" }, status: :not_found
      return
    }

    response = %(
      {
        "foo" : "123",
        "bar" : {
          "whistle" : "feather",
          "ping" : "pong"
        }
      }
    )

    render json: response, status: :ok 
  end
end

When I run this I get:

myuser:myapp myuser$ curl -k http://localhost:3000/widgets

SyntaxError at /widgets
==============================

> syntax error, unexpected '{', expecting keyword_then or ';' or '\n'
/Users/myuser/myapp/app/controllers/widgets_controller.rb:4: syntax error, unexpected ':', expecting =>
      render json: { "error" : "bad path params ...
                              ^
/Users/myuser/myapp/app/controllers/widgets_controller.rb:4: syntax error, unexpected '}', expecting keyword_end
...ad path params" }, status: :not_found
...                               ^
/Users/myuser/myapp/app/controllers/widgets_controller.rb:6: syntax error, unexpected '}', expecting keyword_end

app/controllers/widgets_controller.rb, line 3
----------------------------------------------------

``` ruby
    1   class WidgetsController < ApplicationController
    2     def show
>   3       if(params[:widgetId].to_i <= 0 || params[:fizzbuzzId] <= 0) {
    4         render json: { "error" : "bad path params ID" }, status: :not_found
    5         return
    6       }
    7   
    8       response = %(
```

App backtrace
-------------

 - app/controllers/widgets_controller.rb:3:in `'
 - app/middleware/catch_json_parse_errors.rb:8:in `call'

Full backtrace

Any ideas where I'm going awry?

Upvotes: 0

Views: 433

Answers (1)

Holger Frohloff
Holger Frohloff

Reputation: 1705

You can check whether your params are positive integers by using this:

>> "23".to_i > 0
=> true
>> "foo".to_i > 0
=> false

So you could adept this for your params via params[:widgetId].to_i > 0 Does that make sense to you?

Also if you want to return your error response, you need to return "early" otherwise the controller will complain about a double render:

render json: { "error" : "bad input" }, status: :400 and return

Upvotes: 1

Related Questions