Merge pull request #2279 from mkon/link-conditions

Support conditions in link statements
This commit is contained in:
Benjamin Fleischer 2018-10-31 13:27:28 -05:00 committed by GitHub
commit cb67434b46
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 57 additions and 4 deletions

View File

@ -5,6 +5,7 @@
Breaking changes:
Features:
- [#2279](https://github.com/rails-api/active_model_serializers/pull/2279) Support condition options in serializer link statements
Fixes:

View File

@ -238,6 +238,15 @@ link :other, 'https://example.com/resource'
link(:posts) { link_author_posts_url(object) }
```
Just like attributes, links also support conditions in options
```ruby
link(:secret, if: :internal?) { object.secret_link }
def internal?
instance_options[:context] == :internal
end
```
#### #object
The object being serialized.

View File

@ -22,6 +22,7 @@ module ActiveModel
autoload :Adapter
autoload :Null
autoload :Attribute
autoload :Link
autoload :Association
autoload :Reflection
autoload :BelongsToReflection
@ -275,9 +276,14 @@ module ActiveModel
# link(:self) { "http://example.com/resource/#{object.id}" }
# @example
# link :resource, "http://example.com/resource"
# @example
# link(:callback, if: :internal?), { "http://example.com/callback" }
#
def self.link(name, value = nil, &block)
_links[name] = block || value
def self.link(name, *args, &block)
options = args.extract_options!
# For compatibility with the use case of passing link directly as string argument
# without block, we are creating a wrapping block
_links[name] = Link.new(name, options, block || ->(_serializer) { args.first })
end
# Set the JSON API meta attribute of a serializer.

View File

@ -0,0 +1,21 @@
require 'active_model/serializer/field'
module ActiveModel
class Serializer
# Holds all the data about a serializer link
#
# @example
# class PostSerializer < ActiveModel::Serializer
# link :callback, if: :internal? do
# object.callback_link
# end
#
# def internal?
# instance_options[:internal] == true
# end
# end
#
class Link < Field
end
end
end

View File

@ -482,7 +482,8 @@ module ActiveModelSerializers
# }.reject! {|_,v| v.nil? }
def links_for(serializer)
serializer._links.each_with_object({}) do |(name, value), hash|
result = Link.new(serializer, value).as_json
next if value.excluded?(serializer)
result = Link.new(serializer, value.block).as_json
hash[name] = result if result
end
end

View File

@ -17,7 +17,21 @@ module ActiveModelSerializers
link :yet_another do
"http://example.com/resource/#{object.id}"
end
link :conditional1, if: -> { instance_truth } do
"http://example.com/conditional1/#{object.id}"
end
link :conditional2, if: :instance_falsey do
"http://example.com/conditional2/#{object.id}"
end
link(:nil) { nil }
def instance_truth
true
end
def instance_falsey
false
end
end
def setup
@ -85,7 +99,8 @@ module ActiveModelSerializers
:"link-authors" => 'http://example.com/link_authors',
resource: 'http://example.com/resource',
posts: 'http://example.com/link_authors/1337/posts',
:"yet-another" => 'http://example.com/resource/1337'
:"yet-another" => 'http://example.com/resource/1337',
conditional1: 'http://example.com/conditional1/1337'
}
assert_equal(expected, hash[:data][:links])
end