her
her copied to clipboard
Resources that can't be individually retrieved
I'm working with an API that handles certain resources strangely. Suppose one of these resources is called Thing. The way this API is designed, you can retrieve the collection of things:
GET /things => [{id: 1, thing_name: 'name 1'}, {id: 2, thing_name: 'name 2'}, ...]
But you CANNOT retrieve things individually:
GET /things/2 => 404 error
This means that Her calls like Thing.find(2) or ClassThatHasManyThings.things.find(2) wouldn't work, and I wanted them to. My desired behavior was that only for the resources with this issue, the find and where methods would retrieve the collection, find the desired item within the collection, and return it.
So I created a monkey patch that makes this work. Basically, you can indicate that certain models should use "collection finders." Then, there are alternative find and where methods, which are used instead of the built-in ones only for designated models.
I was thinking of cleaning this up and submitting a pull request, but I have no idea if this API I'm working with is the only weird API with this behavior. Please let me know if you feel this is an issue that could be experienced by others. If so, I'll be happy to submit a patch.
Did you share the monkey patch? I'm running into a similar issue.
OK, this seems to mostly work for me. I had to add very similar code to the Relation and HasManyAssociation classes, which definitely needs to be DRYed up and better tested. https://gist.github.com/mhgoldman/a6654612b69d17204da9
Here's how I'm using this:
- I required these files before my Her setup.
- I added
use_collection_finders(a method I defined in class_methods.rb) at the top of the affected models, right belowinclude Her::Model. That makes it work for calling finders directly on models (i.e. Thing.find). - I added the parameter
use_collection_finders: trueto the affected has_many relationships. that takes care of calling finders on has_many associations.
Now things like this seem to work:
Thing.find(534113)
instance_of_class_that_has_many_things.things.find(534113)
Thing.where(id:"534113",project_id:"37878").fetch
Let me know if this is of any use and I'd be glad to spend some more time cleaning it up and testing it.