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 :extractor option to ::association #152

Conversation

hugopeixoto
Copy link
Contributor

I have the following use case (code simplified for readability):

# BlueprinterFinder#find converts :user into UserSerializer

class ApplicationSerializer < Blueprinter::Base
  def self.association(method, options = {}, &block)
    super(
      method,
      { blueprint: BlueprinterFinder.find(method) }.merge(options),
    )
  end
end

class UserSerializer < ApplicationSerializer
  association :contents do |user, options|
    if options[:version]
      user.content_versions.find_by!(version: options[:version])
    else
      user.content_versions.last
    end
  end
end

class UsersController
  def show
    render json: UserSerializer.render(User.find(params[:id]), version: params[:version])
  end
end

I also needed something like the following:

class CredentialSerializer < ApplicationSerializer
  association :user # pass in credential.version to UserSerializer#render somehow
end

class CredentialsController
  def show
    render json: CredentialSerializer.render(Credential.find(params[:id]))
  end
end

To do this, I tried to override the extractor on the association:

class MyAssociationExtractor < Blueprinter::AssociationExtractor
  def extract(association_name, object, local_options, options={})
    super(
      association_name,
      object,
      local_options.merge(version: object.version),
      options.except(:extractor),
    )
  end
end

class CredentialSerializer < ApplicationSerializer
  association :user, extractor: MyAssociationExtractor
end

::field allows to override the :extractor option, but ::association does not. This PR introduces the ability to override :extractor in associations as well.

Sidenotes/questions:

Is there another way of specifying local_options on associations that I may have missed?

I noticed that apart from the extractor, the differences between ::association and ::field is the option association: true. This option seems to be used in Blueprinter::BaseHelpers#associations, but I don't see where this helper is used. Is it still required?

Copy link
Contributor

@philipqnguyen philipqnguyen left a comment

Choose a reason for hiding this comment

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

Thank you @hugopeixoto !! Yes I think this makes perfect sense and makes the association method more aligned with the rest of the api.

My responses to your questions:

Is there another way of specifying local_options on associations that I may have missed?

No other way that I can think of. I'm not sure how else to solve your problem more elegantly with current api. Although if you have some thoughts on augmenting association in such a way that would allow developers to add additional data to association's local_options more elegantly, I'd appreciate it if you'd share them.

I noticed that apart from the extractor, the differences between ::association and ::field is the option association: true. This option seems to be used in Blueprinter::BaseHelpers#associations, but I don't see where this helper is used. Is it still required?

You're right, it does not seem to be in use anymore and can be removed.

@philipqnguyen philipqnguyen merged commit da0ebb0 into procore-oss:master May 23, 2019
@mcclayton mcclayton mentioned this pull request May 23, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants