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

Create a middleware to normalize object attributes #23

Closed
elliottwilliams opened this issue Aug 21, 2016 · 5 comments
Closed

Create a middleware to normalize object attributes #23

elliottwilliams opened this issue Aug 21, 2016 · 5 comments

Comments

@elliottwilliams
Copy link
Member

For Citybus, station names annoyingly have the stop code included in them. Similarly, some routes have schedule info hand-typed into them.

I'd like to have a generic way to normalize object attributes, probably one configurable on a per-agency basis. I could see it integrating into an agency configuration somewhat like this (please ignore any un-idiomatic ruby):

# in config/citybus.rb
agency.use_middleware Normalize do |object|
  case object
  when Shark::Station
    object.name.sub! /(.*) - .*/, '\1'
  end
end

How does this sound to you? Do you think it should actually happen on the client side?

@elliottwilliams elliottwilliams changed the title Create a middleware to normalize object names Create a middleware to normalize object attributes Aug 21, 2016
@faultyserver
Copy link
Member

faultyserver commented Aug 22, 2016

I think this is a reasonable suggestion for the server to handle. Otherwise, it's just data duplication. The configuration will probably end up in it's own config/normalizer.rb (-r added for convention) to avoid bloating the agency config itself.

Fun fact: CityBus has at least 4 different syntaxes that it uses when including stop codes in station names. I've seen " - ", ": ", "-" and no punctuation at all.

Luckily, the code for removing them is relatively simple, something like this (explanation)

object.name.sub!(/\s*\W*\s*(BUS|TEMP)\d+\s*$/, '')

Shedding the schedule information off of route names might be a little more difficult, depending on the consistency of their syntax (/\(Begins[^\)]+\)/ might be good enough), but it shouldn't be impossibly hard.

Also, your code is pretty idiomatic, assuming there would be more than just when Shark::Station in the case statement.

@elliottwilliams
Copy link
Member Author

Great! Probably okay to put this to the side for now, but let's plan on doing it before 1.0

(regexper looks fantastic—thanks for the link)

@faultyserver
Copy link
Member

As it stands, the block that use_middleware takes is reserved as a configurator, so implementing configurable normalization won't be quite that clean.

Instead, something like this will probably suffice:

agency.use_middleware Normalizer do |config|
  config.on_shark_station = Proc.new do |station|
    station.name.sub!(/\s*\W*\s*(BUS|TEMP)\d+\s*$/, '')
  end

  config.on_shark_route = Proc.new do |route|
    route.name.sub!(/\(Begins[^\)]+\)/, '')
  end

  ...
end

While this isn't quite as clean or immediately semantic, it does have the advantage of avoiding the case...when statement (a precedent for anything exposed as "configurable") and somewhat better separation of type handling.

@faultyserver
Copy link
Member

Actually, having Normalizer configuration in config/citybus.rb doesn't particularly make sense, nor does it follow the precedent set by Transport. It should have it's own configuration file - config/normalizer.rb, and the line in the agency configuration should simply be

agency.use_middleware Normalizer

Since that precedent exists, I think it makes sense to consider removing the reserved configurator block from use_middleware and instead passing it directly to the middleware itself, but that's for another issue.

faultyserver added a commit that referenced this issue Sep 16, 2016
The implementation of this middleware is pretty simple: `Normalizer#call` iterates through all of the arguments in an Event. If a handler has been registered for the argument's type (through `Normalizer.configure`), call that handler to normalize the argument. If no handler exists, nothing is done.
@faultyserver
Copy link
Member

I'm going to mark this closed as of f7b8182. The functionality appears to work as described here, and the configuration is giving desired results in my testing.

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