diff --git a/.rubocop.yml b/.rubocop.yml index 95488f91f..d3487826f 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -1,6 +1,7 @@ AllCops: Excludes: - vendor/** + - bin/** LineLength: Enabled: false diff --git a/CHANGELOG.md b/CHANGELOG.md index 3223768af..929066170 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,8 @@ Next Release ============ +#### Features +* [#510](https://github.com/intridea/grape/pull/510): Support lambda-based default values for params - [@myitcv](https://github.com/myitcv). * Your contribution here. #### Fixes diff --git a/README.md b/README.md index 216f5e938..32ec0c662 100644 --- a/README.md +++ b/README.md @@ -359,11 +359,17 @@ Optional parameters can have a default value. ```ruby params do optional :color, type: String, default: 'blue' + optional :random_number, type: Integer, default: -> { Random.rand(1..100) } + optional :non_random_number, type: Integer, default: Random.rand(1..100) end ``` Parameters can be restricted to a specific set of values with the `:values` option. +Default values are eagerly evaluated. Above `:non_random_number` will evaluate to the same +number for each call to the endpoint of this `params` block. To have the default evaluate +at calltime use a lambda, like `:random_number` above. + ```ruby params do requires :status, type: Symbol, values: [:not_started, :processing, :done] diff --git a/lib/grape/validations/default.rb b/lib/grape/validations/default.rb index dd553010e..b48a0753e 100644 --- a/lib/grape/validations/default.rb +++ b/lib/grape/validations/default.rb @@ -7,7 +7,7 @@ def initialize(attrs, options, required, scope) end def validate_param!(attr_name, params) - params[attr_name] = @default unless params.has_key?(attr_name) + params[attr_name] = @default.is_a?(Proc) ? @default.call : @default unless params.has_key?(attr_name) end def validate!(params) diff --git a/spec/grape/validations/default_spec.rb b/spec/grape/validations/default_spec.rb index 487f53f3f..9a49571aa 100644 --- a/spec/grape/validations/default_spec.rb +++ b/spec/grape/validations/default_spec.rb @@ -32,6 +32,14 @@ class API < Grape::API get '/message' do { id: params[:id], type1: params[:type1], type2: params[:type2] } end + + params do + optional :random, default: -> { Random.rand } + optional :not_random, default: Random.rand + end + get '/numbers' do + { random_number: params[:random], non_random_number: params[:non_random_number] } + end end end end @@ -63,4 +71,16 @@ def app last_response.status.should == 200 last_response.body.should == { id: '1', type1: 'default-type1', type2: 'default-type2' }.to_json end + + it 'sets lambda based defaults at the time of call' do + get("/numbers") + last_response.status.should == 200 + before = JSON.parse(last_response.body) + get("/numbers") + last_response.status.should == 200 + after = JSON.parse(last_response.body) + + before['non_random_number'].should == after['non_random_number'] + before['random_number'].should_not == after['random_number'] + end end