her icon indicating copy to clipboard operation
her copied to clipboard

Resources that can't be individually retrieved

Open mhgoldman opened this issue 10 years ago • 2 comments

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.

mhgoldman avatar Mar 04 '15 23:03 mhgoldman

Did you share the monkey patch? I'm running into a similar issue.

voltechs avatar Mar 05 '15 19:03 voltechs

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 below include Her::Model. That makes it work for calling finders directly on models (i.e. Thing.find).
  • I added the parameter use_collection_finders: true to 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.

mhgoldman avatar Mar 06 '15 03:03 mhgoldman