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 supports for :links and :data options to has_many associations for jsonapi adapter #1282

Closed
wants to merge 1 commit into from

Conversation

tchak
Copy link
Contributor

@tchak tchak commented Oct 20, 2015

This is a rebase from #1028

I hope @lsylvester don't mind :)

I also added more test including the one requested by @joaomdmoura with links + data. I also added support for passing in a hash of urls or proc in order to be able to provide custom links.

I hope we can move forward from here.

@@ -27,6 +27,7 @@ def get_serializer(resource, options = {})
end
serializable_resource = ActiveModel::SerializableResource.new(resource, options)
if serializable_resource.serializer?
serializable_resource.url_helper = self
Copy link
Member

Choose a reason for hiding this comment

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

Thanks for this

👎 We will not include the controller. That would be a huge bug and complexity attractor

I think there's an issue for this, but I think the :context option should be renamed :request_context and be an object named RequestContext that has the methods original_url, query_params, and url_helper, though them's just my thoughts.. but the main this is that we will not pass around a controller instance

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sounds good. Would you be ok with this pr only including hash with proc links option? In the mean time it will allow to manually expose links and we can se for automatic link generator in the feature.

Copy link
Member

Choose a reason for hiding this comment

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

yeah, plus there's already a serialization_scope options, so maybe serialization_context would be good

Copy link
Member

Choose a reason for hiding this comment

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

ref: #1269

@bf4 bf4 added the S: Hold label Oct 20, 2015
@@ -1,6 +1,7 @@
verbose = $VERBOSE
$VERBOSE = nil
class Model
extend ActiveModel::Naming
Copy link
Member

Choose a reason for hiding this comment

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

please remove

@bf4
Copy link
Member

bf4 commented Oct 20, 2015

Thinking aloud: This is a big (important) change. Maybe let's make this smaller and start with the simplest case?

@tchak
Copy link
Contributor Author

tchak commented Oct 20, 2015

@bf4 completely agree about starting smaller.

Supporting only

has_many :posts, links: { related: url }, data: false

and

has_many :posts, links: { related: -> (object, name) { url } }, data: false

sound's like small enough for you?

@bf4
Copy link
Member

bf4 commented Oct 20, 2015

or even just has_many :posts, links: { related: url }, data: false, has_many :posts, links: true etc.

@tchak
Copy link
Contributor Author

tchak commented Oct 20, 2015

@bf4 the problem with has_many :posts, links: { related: url }, data: false is that it is rather useless, as usually an association url will contain parent id...

@beauby
Copy link
Contributor

beauby commented Oct 20, 2015

Yup, @tchak is right. We have basically 3 options here:

  • support uri templates
  • support lambdas/procs
  • define links inside blocks (which is basically the same as the previous option)

@tchak
Copy link
Contributor Author

tchak commented Oct 20, 2015

@beauby my current plan is to simplify this PR to support only proc/lambda. Everything else can be implemented in terms of proc on top of it once we figured out context thing in another PR.

@beauby
Copy link
Contributor

beauby commented Oct 20, 2015

@tchak uri templates is a very interesting option as well, I'm not sure which is best

@tchak tchak force-pushed the jsonapi-link-v-data branch from b7adbb8 to 92dd0ed Compare October 20, 2015 21:50
@tchak
Copy link
Contributor Author

tchak commented Oct 20, 2015

@beauby I completely agree. I am just thinking making it one step at a time.

@tchak tchak force-pushed the jsonapi-link-v-data branch 2 times, most recently from 31cfd12 to 5f81788 Compare October 20, 2015 22:09
@bf4
Copy link
Member

bf4 commented Oct 20, 2015

Link template + link_attributes (like mustache) is easy to understand and switch out impl

Using the template rfc makes building an info response object easier but isn't super high priority

B mobile phone

On Oct 20, 2015, at 4:52 PM, Paul Chavard notifications@github.com wrote:

@beauby I completely agree. I am just thinking making it one step at a time.


Reply to this email directly or view it on GitHub.

@beauby
Copy link
Contributor

beauby commented Oct 22, 2015

We have to be careful when passing data: false not to allow the corresponding associated resource's association to be included via the include option in order not to break the full-linkage property.

@tchak
Copy link
Contributor Author

tchak commented Oct 22, 2015

@beauby Right! I will look in to it.

@tchak tchak force-pushed the jsonapi-link-v-data branch 3 times, most recently from 4ffde66 to f26bde2 Compare October 22, 2015 20:20
@tchak
Copy link
Contributor Author

tchak commented Oct 22, 2015

@beauby I added a bunch of tests to test different combinations of data and include options

@tchak
Copy link
Contributor Author

tchak commented Oct 22, 2015

@bf4 @beauby I want to add uri template but I feel like there is already a lot of stuff in this PR. Would prefer to see it merged and then I will work on a next PR with uri template stuff.

def relationship_links_for(name, owner, options = {})
options[:links].each_with_object({}) do |(key, link), hash|
if link.is_a? Proc
hash[key] = link.call(owner, name)
Copy link
Member

Choose a reason for hiding this comment

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

should be respond_to?(:call)

Copy link
Member

Choose a reason for hiding this comment

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

here and elsewhere

hash[association.key] = {}

if association.options.fetch(:data, true)
hash[association.key][:data] = relationship_data_for(association.serializer, association.options)
Copy link
Member

Choose a reason for hiding this comment

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

oh, interesting, you're re-using the :data key

@bf4
Copy link
Member

bf4 commented Oct 22, 2015

@tchak Looks really good, 💯!

Two more things:

  • needs some examples of how to use either in code comments or in the /docs folder. Explain what data and linksare, how they're used, and that in the absence of the jsonapi adapter, they do nothing.
  • the proc usage makes me really nervous. It seems really inflexible and not very intent-revealing. Would you mind trying with a (roll your own ok) uri template to see how that feels? I think it'll be a lot more user and dev friendly.

@bf4 bf4 removed the S: Hold label Oct 22, 2015
@tchak
Copy link
Contributor Author

tchak commented Oct 22, 2015

@bf4 I was planing on implementing uri template in termes of default proc once this was merged. I think having proc as a backup "power-user" option is good. If you prefer I can add uri template directly to this PR. I am just not sure about all the "variables" I should interpolate with uri template. Obvious one is parent_id. I was actually thinking of making it "named", I mean tag_id in case of Tag serializer with has_many :posts, links: { related: "http://host/tags/{tag_id}/posts" }. Not sure if anything else actually needs to be dynamic.

@richmolj
Copy link
Contributor

I actually really like the procs since I can imagine scenarios the url should be dynamic. Something like:

has_many :posts, proc { |object, name|
  if v2_feature_toggled_on_for_current_user?
    "http://test.host/apt/v2/posts"
  else
    "http://test.host/apt/v1/posts"
  end
}

@bf4
Copy link
Member

bf4 commented Dec 23, 2015

@tchak are we still working on this?

@tchak
Copy link
Contributor Author

tchak commented Dec 23, 2015

@bf4 I will have some time to rebase and cleanup this weekend

@bf4
Copy link
Member

bf4 commented Dec 23, 2015

Awesome!

B mobile phone

On Dec 23, 2015, at 4:49 AM, Paul Chavard notifications@github.com wrote:

@bf4 I will have some time to rebase and cleanup this weekend


Reply to this email directly or view it on GitHub.

@djsegal
Copy link

djsegal commented Dec 24, 2015

Is this supposed to resolve: #834?

@djsegal
Copy link

djsegal commented Dec 25, 2015

While using this, I noticed that I didn't have access to _url helpers, so I added the following line to the serializer, which allows you to do routes.blank_url:

def self.routes
  Rails.application.routes.url_helpers
end

to reduce the repetitiveness of this task,

  • i added a base class ApplicationSerializer < ActiveModel::Serializer serializer file
  • and overwrote the serializer template with my own at lib/templates/rails/serializer/serializer.rb.erb:
<% module_namespacing do -%>
class <%= class_name %>Serializer < ApplicationSerializer
  attributes <%= attributes_names.map(&:inspect).join(", ") %>
<% association_names.each do |attribute| -%>
  has_one :<%= attribute %>
<% end -%>
end
<% end -%>

@bf4
Copy link
Member

bf4 commented Dec 25, 2015

@djsegal The url handling is going to be in the serialization_context #1313, but just hasn't been finished. Would you like to give it a shot?

@beauby
Copy link
Contributor

beauby commented Jan 21, 2016

ref #1454

@remear
Copy link
Member

remear commented Mar 17, 2016

@rails-api/ams Is this still relevant?

@groyoh
Copy link
Member

groyoh commented Mar 30, 2016

@remear no, it's closed by #1454.

@groyoh groyoh closed this Mar 30, 2016
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.

7 participants