If you're using Rails 4 style scopes which require a callable block (e.g., lambda) that doesn't take any args you'll run into some trouble with Brainstem. Example:
Say I have a Rails 3 style scope that looks like this:
scope :current, where(:current => true)
This works fine if I want to send a request for entities in that scope:
GET /coolsite/api/v1?current=true
But say I convert it to a Rails 4 style scope with a lambda:
scope :current, -> { where(:current => true) }
This will cause things to explode with Exception: wrong number of arguments (1 for 0)
because of how PresenterCollection.run_filters
works. It will extract "true" as an argument that you want to pass to the scope, and call it with scope = scope.send(filter_name, arg)
(passing in true
as the arg
). And since the scope doesn't take an argument, we get screamed at.
I've been thinking about this, and I cannot come up with a good solution to this. The problem is that there's no good way for Brainstem to actually know (that I'm aware of) that I didn't want to pass an argument to that lambda.
The other option is to refactor any lambda's that are interacting w/Brainstem to include an optional arg. e.g., rewrite that scope as scope :current, ->(current=true) { where(:current => current) }
. I don't like this because it requires somebody interacting with Brainstem to refactor their code because of its internal behavior (leaky abstraction).
If there's some Ruby magic that would allow Brainstem to introspect the scope and see if it's a lambda that accepts 0 arguments (and then just call scope = scope.send(filter_name)
in PresenterCollection.run_filters
) that would be best, I think. I haven't figured out if that's possible yet, but I'll look into it.
I've been messing around with scope.method(filter_name)
but with no luck. .arity
always returns -1 and .parameters
is also not helpful. Hoping there's some other type of introspection that could help here.