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

Add support for dynamic string-links in JsonApi adapter. #1406

Merged
merged 1 commit into from
Jan 15, 2016

Conversation

beauby
Copy link
Contributor

@beauby beauby commented Dec 29, 2015

Solves #1400.

@@ -13,6 +13,10 @@ class LinkAuthorSerializer < ActiveModel::Serializer
end

link :other, '//example.com/resource'
Copy link
Member

Choose a reason for hiding this comment

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

Off topic: given that JSON API is undecided on relative links, I'd rather not fill our examples with them

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Agreed, however this is not a relative link. //resource would be undefined, but //example.com/resource is a valid url.

Copy link
Member

Choose a reason for hiding this comment

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

@beauby words... words.. I meant 'protocol relative'. Sorry I typo'ed again :(

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't feel strongly about this, although it is not clear from the discussion whether they are disallowing relative urls or protocol-relative urls.

Copy link
Member

Choose a reason for hiding this comment

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

Yeah, I just updated my question to clarify that

@bf4
Copy link
Member

bf4 commented Dec 30, 2015

@beauby Made a PR into this proposing a Link interface more similar to what we've been doing in Reflection and Attribute beauby#2

end

def serializable_hash
Copy link
Member

Choose a reason for hiding this comment

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

I'm not sure if serializable_hash is a good name considering it can be a string. What's your point on this?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Indeed, it is not a perfect name. The rationale was that serializable_hash is already used all around in AMS for objects that are "ready to be transformed into JSON", i.e. no further treatment is required (used in SerializableResource.new(resource).serializable_hash, PaginationLink.new(stuff).serializable_hash).

Copy link
Member

Choose a reason for hiding this comment

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

@groyoh @beauby What not have a value method like our other 'value' objects, Reflection, Attribute..?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@bf4 I'm not satisfied with value but you're right, it's probably better to keep it consistent for now and possibly update everything in a subsequent commit.

Copy link
Member

Choose a reason for hiding this comment

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

I think it mainly looks weird because we're passing value into. Maybe just have as_json and to_json?

Copy link
Member

Choose a reason for hiding this comment

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

(but in a follow-up PR)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

as_json is the way to go IMO (for the record, as_json means build something ready to be directly transformed into JSON, i.e. a Hash mainly, but we could extend the meaning to be "something that will eventually be part of a Hash representing a JSON document", and to_json means actually building a JSON string from the object).

Copy link
Member

Choose a reason for hiding this comment

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

👍

if value.respond_to?(:call)
self._value = instance_eval(&value)
else
self._value = value
Copy link
Member

Choose a reason for hiding this comment

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

What's our desired behavior if someone does

link :foo do
  meta 'thing'
  'https://example.com/doohickie'
end

?

right now it would only return the block's return value

Copy link
Member

Choose a reason for hiding this comment

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

We should also probably comment that in the block form, if meta and/or href are used, value is nil and the Link is an object. If neither are used, the Link is a URI (the return value of the block). If both are used and the block has a return value....?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The way I see it, providing a return value to the block should be interpreted as "I'm a big boy and this is my link value". Otherwise, "building" a link object through the DSL should be done, well, via the DSL. What are your thoughts?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Agreed that it should be stated clearly.

Copy link
Member

Choose a reason for hiding this comment

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

So, let's update and warn against the scenario in https://github.com/rails-api/active_model_serializers/pull/1406/files#r48668245 and ok to merge

Copy link
Member

Choose a reason for hiding this comment

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

@beauby
Copy link
Contributor Author

beauby commented Jan 12, 2016

All concerns taken care of. I'll merge later today unless someone raises other concerns.

attr_reader :object, :scope

private

def to_hash
Copy link
Member

Choose a reason for hiding this comment

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

block_value || hash_value ? to_hash doesn't really jive well with how I think of the method

Copy link
Member

Choose a reason for hiding this comment

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

granted, this is internal api, so just talking about naming

@bf4
Copy link
Member

bf4 commented Jan 12, 2016

@beauby Please add changelog and docs, and it's good to go. I don't really like the internals of the Link object, particularly the naming of _value vs. to_hash-- I don't find them very descriptive-- but I can live with it. Otherwise, 💯


# Use the return value of the block unless it is nil.
if value.respond_to?(:call)
self._value = instance_eval(&value)
Copy link
Member

Choose a reason for hiding this comment

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

Could you please explain why you used an attr_accessor for _value instead of using a reader and calling @_value = instance_eval(&value)? I don't see why _value is different than object or scope.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

You're right, there's no reason. There just seemed to be a trend (which I kinda disapprove actually) in AMS to move towards accessors rather than ivars. I'll update it.

Copy link
Member

Choose a reason for hiding this comment

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

agreed it should be a naked instance variable here

my general thinking: setters and getters are, all things being equal, a better way to handle accessing instance values, since it protects the code against changes and typos. However, there's no need to message dispatch when setting the value in an initializer, so a reader-only is fine there. As to eschewing accessors all together, I'd probably only do that for performance reasons, or when maybe when I'm certain there code won't change often so mis-typing a variable name is unlikely.

@bf4 bf4 added the S: LGTM label Jan 15, 2016
@bf4
Copy link
Member

bf4 commented Jan 15, 2016

@beauby squash commits, add changelog and good to merge. I want to release rc4 soon so am trying to get whatever prs with good features that can be merged, in.

@beauby beauby force-pushed the dynamic-jsonapi-string-links branch 3 times, most recently from cb35d6d to 38b71ea Compare January 15, 2016 13:03
@beauby
Copy link
Contributor Author

beauby commented Jan 15, 2016

PR ready, waiting for Travis.

@beauby beauby force-pushed the dynamic-jsonapi-string-links branch from 38b71ea to 30d8414 Compare January 15, 2016 13:36
beauby added a commit that referenced this pull request Jan 15, 2016
Add support for custom dynamic valued links in JsonApi adapter.
@beauby beauby merged commit b9f4720 into rails-api:master Jan 15, 2016
@beauby beauby deleted the dynamic-jsonapi-string-links branch April 22, 2016 09:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants