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

How to add attributes via Middleware #20

Closed
faultyserver opened this issue Aug 17, 2016 · 3 comments
Closed

How to add attributes via Middleware #20

faultyserver opened this issue Aug 17, 2016 · 3 comments
Milestone

Comments

@faultyserver
Copy link
Member

#16 outlines a potential case where a Middleware would create a new attribute neighborhood on Vehicle. If the middleware is not present, this attribute will never be populated, and should therefore not be part of the default Vehicle model.

The question, then, is this: How can a middleware define new attributes for a model? These attributes need to be included in the appropriate object.class.attributes list in order to be serializable, but should not require users to modify the Object classes manually when adding middlewares.

A simple solution, it seems, would be to add a Middleware#installed callback that is called after a Middleware instance is installed into the stack for an agency. Middlewares could then do anything in response, including dynamically modify Object attributes. For example, to add a neighborhood attribute to Shark::Vehicle:

class AttributeModifyingMiddleware < Shark::Middleware
  # The callback will include a reference to the agency that this middleware
  # was just installed in.
  def installed agency
    # Add a new `neighborhood` attribute to `Shark::Vehicle`
    Shark::Vehicle.attribute :neighborhood
  end
end

An issue with this approach is that there is no longer a canonical location where all attributes of a model are listed. However, the list is always dynamically available through object.class.attributes, which should be sufficient for most cases.

@elliottwilliams
Copy link
Member

Makes sense to me. The canonical attribute list, as it currently is, isn't perfect anyways. It's typelessness has made me usually look at serialized objects when building decoders. A future system could dynamically generate more thorough object attribute documentation (something like ActiveRecord's schema.rb), but I'm fine with this approach for now.

@faultyserver
Copy link
Member Author

Agreed. I'm working on a schema system that supplies expectations and type requirements for Configuration right now, so hopefully I'll be able to apply that to models before long.

@faultyserver
Copy link
Member Author

faultyserver commented Aug 21, 2016

533c607 and 65fde3e have been implementing a Schemable module, which should solve this, at least from a descriptive angle.

All Shark::Object classes have a schema property that contains all of the information about the expected structure of an Object. This currently includes attribute names, requiredness, default values, value aliases, and type information (though types are not currently enforced). All instances of these classes can reference their schema through self.class.schema.

There could potentially be a rake task or similar that loads an agency, reads these schemas, and dumps a schema.json or something for the sake of complete documentation.

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

2 participants