Skip to content

add ability to use Grape::Entity documentation in the params block #562

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ Next Release
* [#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).
* [#560](https://github.com/intridea/grape/pull/560): `require` now accepts a 'using' option that defined multiple required and optional fields. - [@reynardmh](https://github.com/reynardmh).
* Your contribution here.

#### Fixes
Expand Down
2 changes: 1 addition & 1 deletion Guardfile
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# A sample Guardfile
# More info at https://github.com/guard/guard#readme

guard 'rspec', :version => 2 do
guard 'rspec' do
watch(%r{^spec/.+_spec\.rb$})
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
watch(%r{^spec/support/shared_versioning_examples.rb$}) { |m| "spec/" }
Expand Down
21 changes: 21 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1187,6 +1187,27 @@ module API
end
```

You can use entity documentation in the params block
```ruby
class User::Entity < Grape::Entity
expose :id, documentation: { type: Integer}
expose :name, documentation: { type: String, desc: "Name" }
expose :email, documentation: { type: String, desc: "Email address" }
end

class Users < Grape::API
desc 'Create user'
params do
requires :all, except: [:name], using: User::Entity.documentation.except(:id)
end
post 'users' do
# implement create user
end
end

```


You can present with multiple entities using an optional Symbol argument.

```ruby
Expand Down
38 changes: 32 additions & 6 deletions lib/grape/validations.rb
Original file line number Diff line number Diff line change
Expand Up @@ -108,13 +108,16 @@ def should_validate?(parameters)
def requires(*attrs, &block)
orig_attrs = attrs.clone

validations = { presence: true }
validations.merge!(attrs.pop) if attrs.last.is_a?(Hash)
validations[:type] ||= Array if block_given?
validates(attrs, validations)
opts = attrs.last.is_a?(Hash) ? attrs.pop : nil

block_given? ? new_scope(orig_attrs, &block) :
push_declared_params(attrs)
if opts && opts[:using]
require_required_and_optional_fields(attrs.first, opts)
else
validate_attributes(attrs, opts, &block)

block_given? ? new_scope(orig_attrs, &block) :
push_declared_params(attrs)
end
end

def optional(*attrs, &block)
Expand Down Expand Up @@ -172,6 +175,29 @@ def push_declared_params(attrs)

private

def require_required_and_optional_fields(context, opts)
if context == :all
optional_fields = opts[:except].is_a?(Array) ? opts[:except] : [opts[:except]].compact
required_fields = opts[:using].keys - optional_fields
else # attrs.first == :none
required_fields = opts[:except].is_a?(Array) ? opts[:except] : [opts[:except]].compact
optional_fields = opts[:using].keys - required_fields
end
required_fields.each do |field|
requires(field, opts[:using][field])
end
optional_fields.each do |field|
optional(field, opts[:using][field])
end
end

def validate_attributes(attrs, opts, &block)
validations = { presence: true }
validations.merge!(opts) if opts
validations[:type] ||= Array if block
validates(attrs, validations)
end

def new_scope(attrs, optional = false, &block)
opts = attrs[1] || { type: Array }
raise ArgumentError unless opts.keys.to_set.subset? [:type].to_set
Expand Down