Skip to content

Commit

Permalink
Merge pull request #550 from dm1try/named_params
Browse files Browse the repository at this point in the history
Add possibility to define reusable params.
  • Loading branch information
dblock committed Jan 7, 2014
2 parents 19dbe48 + 92d5c46 commit b760958
Show file tree
Hide file tree
Showing 5 changed files with 155 additions and 1 deletion.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ Next Release
* [#540](/~https://github.com/intridea/grape/pull/540): Ruby 2.1.0 is now supported - [@salimane](/~https://github.com/salimane).
* [#544](/~https://github.com/intridea/grape/pull/544): The `rescue_from` keyword now handles subclasses of exceptions by default - [@xevix](/~https://github.com/xevix).
* [#545](/~https://github.com/intridea/grape/pull/545): Added `type` (Array or Hash) support to `requires`, `optional` and `group` - [@bwalex](/~https://github.com/bwalex).
* [#550](/~https://github.com/intridea/grape/pull/550): Added possibility to define reusable params - [@dm1try](/~https://github.com/dm1try).
* Your contribution here.

#### Fixes
Expand Down
52 changes: 52 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -576,6 +576,58 @@ class API < Grape::API
end
```

You can define reusable `params` using `helpers`.

```ruby
class API < Grape::API
helpers do
params :pagination do
optional :page, type: Integer
optional :per_page, type: Integer
end
end

desc "Get collection"
params do
use :pagination # aliases: includes, use_scope
end
get do
Collection.page(params[:page]).per(params[:per_page])
end
end
```

You can also define reusable `params` using shared helpers.

```ruby
module SharedParams
extend Grape::API::Helpers

params :period do
optional :start_date
optional :end_date
end

params :pagination do
optional :page, type: Integer
optional :per_page, type: Integer
end
end

class API < Grape::API
helpers SharedParams

desc "Get collection"
params do
use :period, :pagination
end
get do
Collection.from(params[:start_date]).to(params[:end_date])
.page(params[:page]).per(params[:per_page])
end
end
```

## Cookies

You can set, get and delete your cookies very simply using `cookies` method.
Expand Down
36 changes: 35 additions & 1 deletion lib/grape/api.rb
Original file line number Diff line number Diff line change
Expand Up @@ -268,11 +268,16 @@ def helpers(new_mod = nil, &block)
if block_given? || new_mod
mod = settings.peek[:helpers] || Module.new
if new_mod
inject_api_helpers_to_mod(new_mod) if new_mod.is_a?(Helpers)
mod.class_eval do
include new_mod
end
end
mod.class_eval(&block) if block_given?
if block_given?
inject_api_helpers_to_mod(mod) do
mod.class_eval(&block)
end
end
set(:helpers, mod)
else
mod = Module.new
Expand Down Expand Up @@ -509,6 +514,12 @@ def inherit_settings(other_stack)
e.options[:app].inherit_settings(other_stack) if e.options[:app].respond_to?(:inherit_settings, true)
end
end

def inject_api_helpers_to_mod(mod, &block)
mod.extend(Helpers)
yield if block_given?
mod.api_changed(self)
end
end

def initialize
Expand Down Expand Up @@ -581,5 +592,28 @@ def add_head_not_allowed_methods_and_options_methods
end
end
end

# This module extends user defined helpers
# to provide some API-specific functionality
module Helpers
attr_accessor :api
def params(name, &block)
@named_params ||= {}
@named_params.merge! name => block
end

def api_changed(new_api)
@api = new_api
process_named_params
end

protected

def process_named_params
if @named_params && @named_params.any?
api.imbue(:named_params, @named_params)
end
end
end
end
end
12 changes: 12 additions & 0 deletions lib/grape/validations.rb
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,18 @@ def params(params)
params
end

def use(*names)
named_params = @api.settings[:named_params] || {}
names.each do |name|
params_block = named_params.fetch(name) do
raise "Params :#{name} not found!"
end
instance_eval(&params_block)
end
end
alias_method :use_scope, :use
alias_method :includes, :use

def full_name(name)
return "#{@parent.full_name(@element)}[#{name}]" if @parent
name.to_s
Expand Down
55 changes: 55 additions & 0 deletions spec/grape/validations_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -698,5 +698,60 @@ def validate_param!(attr_name, params)
end
end
end # end custom validation

context 'named' do
context 'can be defined' do
it 'in helpers' do
subject.helpers do
params :pagination do
end
end
end

it 'in helper module which kind of Grape::API::Helpers' do
module SharedParams
extend Grape::API::Helpers
params :pagination do
end
end
subject.helpers SharedParams
end
end

context 'can be included in usual params' do
before do
module SharedParams
extend Grape::API::Helpers
params :period do
optional :start_date
optional :end_date
end
end
subject.helpers SharedParams

subject.helpers do
params :pagination do
optional :page, type: Integer
optional :per_page, type: Integer
end
end
end

it 'by #use' do
subject.params do
use :pagination
end
subject.settings[:declared_params].should eq [:page, :per_page]
end

it 'by #use with multiple params' do
subject.params do
use :pagination, :period
end
subject.settings[:declared_params].should eq [:page, :per_page, :start_date, :end_date]
end

end
end
end
end

0 comments on commit b760958

Please sign in to comment.