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

Implement association as it's own thing #407

Open
1 task done
sandstrom opened this issue Mar 21, 2024 · 15 comments
Open
1 task done

Implement association as it's own thing #407

sandstrom opened this issue Mar 21, 2024 · 15 comments
Assignees

Comments

@sandstrom
Copy link

Is there an existing issue for this?

  • I have searched the existing issues

Is your feature request related to a problem? Please describe

Right now, association is internally implemented as a field, with a magic :assocation option.

Describe the feature you'd like to see implemented

I'd implement association as a proper class internally, similar to Field.

    def self.association(method, options = {}, &block)
      validate_blueprint!(options[:blueprint], method)

      make_association(
        method,
        options.merge(
          extractor: options.fetch(:extractor) { AssociationExtractor.new }
        ),
        &block
      )
    end

Describe alternatives you've considered

No response

Additional context

No response

@sandstrom sandstrom mentioned this issue Mar 21, 2024
1 task
@sandstrom
Copy link
Author

Happy to discuss this in more detail, and elaborate more.

@sandstrom
Copy link
Author

Friendly ping @lessthanjacob @njbbaer @ritikesh

If you think this is a reasonable suggestion, let me know! If so, I'd propose these steps:

  • I'll flesh out the proposed change in some more detail (written, in this issue)
  • You get another chance to provide more feedback, and if you're happy we'll open a PR

For reference, there are also a few other issues that I've opened, where I'd also be happy to get your input.

Full list

@sandstrom
Copy link
Author

Friendly ping @lessthanjacob @njbbaer @ritikesh

Happy to hear your thoughts on this!

@ritikesh
Copy link
Collaborator

What would the responsibilities be of this Association class outside of how it's being handled within the ViewCollection/View contexts today?

@sandstrom
Copy link
Author

It would be a sibling class next to Field. It would work just the same as the Field class does today.

Mostly just seemed like a design that's easier to comprehend, because right now an association is a field with the "magic" option called :association with value true.

That said, I don't feel strongly about this.

An alternative would be to turn it into a property on the field (similar to what's proposed for the other magic options in #405).

@ritikesh
Copy link
Collaborator

They do behave similarly. It's just a readability thing with no major functional differences barring associations having their own blueprinter/view based rendering.

An alternative would be to turn it into a property on the field (similar to what's proposed for the other magic options in #405).

At this point, I'm not strongly for/against this one either. But the trend seems to be in the direction of major rewrites and as long as there's no/little impact to the consumers, this should still be ok.

@jmeridth / @njbbaer - any thoughts from your side?

@ritikesh
Copy link
Collaborator

in fact, many fields have additional options too - like date_time formatter (which we're planning to get rid off too in favour of extractors). If we're able to achieve consistency in terms of the options that required for defining a field and an association with them being unique to their own types, then I think this might make more sense.

Copy link

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@sandstrom
Copy link
Author

Not stale

@lessthanjacob
Copy link
Contributor

I didn't link this issue, but I recently started down this path with #414, albeit in a very rudimentary way for the time being.

# frozen_string_literal: true
require_relative 'field'
require_relative 'blueprint_validator'
module Blueprinter
# @api private
class Association < Field
# @param method [Symbol] The method to call on the source object to retrieve the associated data
# @param name [Symbol] The name of the association as it will appear when rendered
# @param blueprint [Blueprinter::Base] The blueprint to use for rendering the association
# @param view [Symbol] The view to use in conjunction with the blueprint
# @param extractor [Blueprinter::Extractor] The extractor to use when retrieving the associated data
# @param options [Hash]
#
# @return [Blueprinter::Association]
def initialize(method:, name:, blueprint:, view:, extractor: AssociationExtractor.new, options: {})
BlueprintValidator.validate!(blueprint)
super(
method,
name,
extractor,
blueprint,
options.merge(
blueprint: blueprint,
view: view,
association: true
)
)
end
end
end

This makes the interface a bit more explicit/clearer, but there's room to take this further, since it's mostly functioning as a facade around Field.new anyway.

@sandstrom
Copy link
Author

This makes the interface a bit more explicit/clearer, but there's room to take this further, since it's mostly functioning as a facade around Field.new anyway.

That's great!

Copy link

github-actions bot commented Sep 5, 2024

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@sandstrom
Copy link
Author

Not stale

Copy link

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@sandstrom
Copy link
Author

Not stale

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants