Grape: declared(params) strips out default values from optional params before validation

Created on 4 Sep 2015  路  10Comments  路  Source: ruby-grape/grape

I have noticed that @permitted_params = declared(params) will set to null any optional param values when they have a default value set and they have not been passed in the call to an endpoint.

Ideally I think that optional param values should be included in the params returned by the declared method. But this is not what I am seeing.

In other words. If a param that is optional, that has not been passed in the call to the endpoint, but which has a default value specified in the param validation, in the endpoint the param will be in the params array and it will have the default value. However, when passing params through the declared method the returned array has the optional param but the default value has been lost and instead the value is null.

bug?

Most helpful comment

@giedriusr I believe you're looking for declared(params, include_missing: false).

All 10 comments

Thought I'd try to provide some example code here in case I'm doing something wrong.

# -- param_validation.rb

module ParamValidation
  extend Grape::API::Helpers

  params :optional_gizmo do |options|
    optional :gizmo, type: String, default: options[:default_gizmo], values: ['valid_value1', 'valid_value2'], allow_blank: false
  end
end

# -- v1.rb

require_relative 'param_validation.rb'

module API
  class V1 < Grape::API

    version 'v1', :using => :path
    prefix :api
    default_format :json
    format :json
    helpers ParamValidation

    params do
      use :optional_gizmo, default_gizmo: 'valid_value2'
    end
    namespace 'ns1' do

      get 'endpoint1' do
        { "declared_params" => declared(params) }
      end

    end

  end
end

A GET request to /api/v1/endpoint1 will output : { "declared_params" : { "gizmo" : null } }

Anyone any ideas on this one? Is it a confirmed bug or am I doing something wrong?

@atomless I have tried to reproduce it, but I can't. I have tried with the code you posted, but I get the expected result:

{
  "declared_params": {
    "gizmo": "valid_value2"
  }
}

Are you using the last version of grape? Is there any other thing which may be affecting your result?

Sorry to not have got back to this before now. You're correct, I found that the example I provided didn't reproduce the issue either. Checking how we do it in our code base, I see that the declared call is actually in the "before_validation do" hook. When in there it does still wipe all values to null. Moving it to the "after_validation do" hook and it all works perfectly.

Can this be closed @atomless? (please feel free to)

@dblock - up to you. Depends whether wiping of the pram values is the desired outcome when calling declared(params) from the before validation method? Seems unintuitive to me. I would expect to be able to call declared params before validation was applied, although I can understand why that might be a little weird too.

I've updated the title to say "before validation". I think you should try to turn this into a spec, @atomless and we can see if we can fix it. I am not convinced we should, but it would at least move us forward.

Is this considered normal thing that params which are optional and not passed gets NULL value? For me it doesn't make sense.

(byebug) params
#<Hashie::Mash access_token="abcdef" date="2016-06-15T09:11:07Z" seats="4" token="some_token">
(byebug) declared(params)
#<Hashie::Mash date="2016-06-15T09:11:07Z" menu_id=nil price=nil seats="4" token="some_token">

UPDATE: nevermind, found that include_missing: false is the way to go.

@giedriusr I believe you're looking for declared(params, include_missing: false).

Yes, I found out it a bit later. Thanks!

Was this page helpful?
0 / 5 - 0 ratings