Skip to content
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

Follow up to #1454 #1504

Merged
merged 2 commits into from
Feb 12, 2016
Merged
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
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
## 0.10.x

Breaking changes:

Features:
- [#1504](https://github.com/rails-api/active_model_serializers/pull/1504) Adds the changes missing from #1454
and add more tests for resource identifier and relationship objects. (@groyoh)
- [#1018](https://github.com/rails-api/active_model_serializers/pull/1018) Add more tests and docs for top-level links. (@leandrocp)
- [#1454](https://github.com/rails-api/active_model_serializers/pull/1454) Add support for
relationship-level links and meta attributes. (@beauby)
- [#1340](https://github.com/rails-api/active_model_serializers/pull/1340) Add support for resource-level meta. (@beauby)

Fixes:
- [#1501](https://github.com/rails-api/active_model_serializers/pull/1501) Adds tests for SerializableResource::use_adapter?,doc typos (@domitian)
- [#1488](https://github.com/rails-api/active_model_serializers/pull/1488) Require ActiveSupport's string inflections (@nate00)

Misc:

### v0.10.0.rc4 (2016/01/27 11:00 +00:00)
Expand Down
14 changes: 7 additions & 7 deletions lib/active_model/serializer/adapter/json_api.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,9 @@ class JsonApi < Base
autoload :PaginationLinks
autoload :FragmentCache
autoload :Link
autoload :Association
autoload :ResourceIdentifier
autoload :Meta
autoload :Deserialization
require 'active_model/serializer/adapter/json_api/api_objects'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, in https://github.com/rails-api/active_model_serializers/pull/1004/files#r52563837 I noticed that we've already started a pattern of sticking the json_api objects in the json_api folder. e.g. above we have Meta and Link which are also json_api object.

In code I removed I move that object into json_api/jsonapi.rb. What do you think about just sticking also the api objects in the json_api folder as we've essentially already been doing?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's fine by me. Should I still keep the ApiObjects namespace?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NEEDS FOLLOWUP


# TODO: if we like this abstraction and other API objects to it,
# then extract to its own file and require it.
Expand Down Expand Up @@ -100,7 +99,7 @@ def resource_objects_for(serializers)
end

def process_resource(serializer, primary)
resource_identifier = JsonApi::ResourceIdentifier.new(serializer).as_json
resource_identifier = ApiObjects::ResourceIdentifier.new(serializer).as_json
return false unless @resource_identifiers.add?(resource_identifier)

resource_object = resource_object_for(serializer)
Expand Down Expand Up @@ -136,7 +135,7 @@ def attributes_for(serializer, fields)

def resource_object_for(serializer)
resource_object = cache_check(serializer) do
resource_object = JsonApi::ResourceIdentifier.new(serializer).as_json
resource_object = ApiObjects::ResourceIdentifier.new(serializer).as_json

requested_fields = fieldset && fieldset.fields_for(resource_object[:type])
attributes = attributes_for(serializer, requested_fields)
Expand All @@ -160,12 +159,13 @@ def resource_object_for(serializer)
def relationships_for(serializer, requested_associations)
include_tree = IncludeTree.from_include_args(requested_associations)
serializer.associations(include_tree).each_with_object({}) do |association, hash|
hash[association.key] = JsonApi::Association.new(serializer,
hash[association.key] = ApiObjects::Relationship.new(
serializer,
association.serializer,
association.options,
association.links,
association.meta)
.as_json
association.meta
).as_json
end
end

Expand Down
13 changes: 13 additions & 0 deletions lib/active_model/serializer/adapter/json_api/api_objects.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
module ActiveModel
class Serializer
module Adapter
class JsonApi
module ApiObjects
extend ActiveSupport::Autoload
autoload :Relationship
autoload :ResourceIdentifier
end
end
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
module ActiveModel
class Serializer
module Adapter
class JsonApi
module ApiObjects
class Relationship
def initialize(parent_serializer, serializer, options = {}, links = {}, meta = nil)
@object = parent_serializer.object
@scope = parent_serializer.scope

@options = options
@data = data_for(serializer, options)
@links = links.each_with_object({}) do |(key, value), hash|
hash[key] = Link.new(parent_serializer, value).as_json
end
@meta = meta.respond_to?(:call) ? parent_serializer.instance_eval(&meta) : meta
end

def as_json
hash = {}
hash[:data] = data if options[:include_data]
links = self.links
hash[:links] = links if links.any?
meta = self.meta
hash[:meta] = meta if meta

hash
end

protected

attr_reader :object, :scope, :data, :options, :links, :meta

private

def data_for(serializer, options)
if serializer.respond_to?(:each)
serializer.map { |s| ResourceIdentifier.new(s).as_json }
else
if options[:virtual_value]
options[:virtual_value]
elsif serializer && serializer.object
ResourceIdentifier.new(serializer).as_json
end
end
end
end
end
end
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
module ActiveModel
class Serializer
module Adapter
class JsonApi
module ApiObjects
class ResourceIdentifier
def initialize(serializer)
@id = id_for(serializer)
@type = type_for(serializer)
end

def as_json
{ id: id, type: type }
end

protected

attr_reader :id, :type

private

def type_for(serializer)
return serializer._type if serializer._type
if ActiveModelSerializers.config.jsonapi_resource_type == :singular
serializer.object.class.model_name.singular
else
serializer.object.class.model_name.plural
end
end

def id_for(serializer)
serializer.read_attribute_for_serialization(:id).to_s
end
end
end
end
end
end
end
48 changes: 0 additions & 48 deletions lib/active_model/serializer/adapter/json_api/association.rb

This file was deleted.

This file was deleted.

13 changes: 9 additions & 4 deletions lib/active_model/serializer/reflection.rb
Original file line number Diff line number Diff line change
Expand Up @@ -42,25 +42,30 @@ def initialize(*)

def link(name, value = nil, &block)
@_links[name] = block || value
nil
:nil
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if this should be called :nil or something else. I actually wanted to have your input on this as I was not too creative here.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is to signify something like :block_returned_nil_value?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. For more details, there are two use cases to consider for the relationship block:

  • Where the block return the value we want to use for the relationship:
has_one :author do
  meta some: :thing
  object.own_author
end
  • Where the block return some value to define that we want to use the default relationship:
has_one :author do
  meta some: :thing
end

For the latest, I defined the value to be :nil but it could be change to anything else if a better suggestion pops up since this is the internal API.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe create an issue or start a pr to discuss any improvements

B mobile phone

On Feb 12, 2016, at 6:11 PM, Yohan Robert [email protected] wrote:

In lib/active_model/serializer/reflection.rb:

@@ -42,17 +42,17 @@ def initialize(*)

   def link(name, value = nil, &block)
     @_links[name] = block || value
  •    nil
    
  •    :nil
    
    Yes. For more details, there are two use cases to consider for the relationship block:

Where the block return the value we want to use for the relationship:
has_one :author do
meta some: :thing
object.own_author
end
Where the block return some value to define that we want to use the default relationship:
has_one :author do
meta some: :thing
end
For the latest, I defined the value to be :nil but it could be change to anything else if a better suggestion pops up since this is the internal API.


Reply to this email directly or view it on GitHub.

end

def meta(value = nil, &block)
@_meta = block || value
nil
:nil
end

def include_data(value = true)
@_include_data = value
nil
:nil
end

def value(serializer)
@object = serializer.object
@scope = serializer.scope

if block
instance_eval(&block)
block_value = instance_eval(&block)
if block_value == :nil
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This assumes that a relationship value (or at least a relationship defined in a block value) MUST never be :nil. I guess this is a safe choice but let me know if you disagree.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

serializer.read_attribute_for_serialization(name)
else
block_value
end
else
serializer.read_attribute_for_serialization(name)
end
Expand Down
Loading