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

Invalid path error thrown too early for URIs with other IDs #90

Closed
paulvt opened this issue Dec 18, 2017 · 6 comments
Closed

Invalid path error thrown too early for URIs with other IDs #90

paulvt opened this issue Dec 18, 2017 · 6 comments

Comments

@paulvt
Copy link

paulvt commented Dec 18, 2017

If the URI of a relation contains another (parent) ID, retrieving the object fails with a Skype::InvalidPathError before it is even checked whether the ID is not nil. The expected behaviour would be to just return nil if the ID for the relation is not set. For example:

class Recipe < Spyke::Base
  belongs_to :user
  has_many :ingredients
end

class User < Spyke::Base
end

class Ingredient
  belongs_to :group, uri: "ingredients/:ingredient_id/groups/:id"
end

class Group < Spyke::Base
end

recipe = Recipe.find(1)
recipe.user_id # => nil
recipe.user # => nil

ingredient = recipe.ingredients.first
ingredient.group_id # => nil
ingredient.group # => raises Spyke::InvalidPathError instead of returning nil

More specifically, the last call raises the exception:

Spyke::InvalidPathError: Missing required variables: ingredient_id, id in ingredients/:ingredient_id/group. Mark optional variables with parens eg: (:param)
@balvig
Copy link
Owner

balvig commented Dec 19, 2017

Thanks for submitting the issue @paulvt!

Would it be possible to include the JSON responses for the examples? I think the InvalidPathError might be getting raised because the id is missing from the first ingredient recipe.ingredients.first, but I'm not entirely sure.

Even better if you can reproduce the problem with a test, for example taking inspiration from https://github.com/balvig/spyke/blob/master/test/associations_test.rb

@paulvt
Copy link
Author

paulvt commented Dec 20, 2017

Ok, the problem seems to be unrelated to chaining/nesting of relations (and thus #89). The issue seems to be that an InvalidPathError exception is thrown if the ID is missing to retrieve the object. This is somewhat unexpected behaviour to us. If the ID is not set, there is just no related object IMO.

The test to show what I mean is as follows:

    def test_return_nil_for_missing_id
      stub_request(:get, 'http://sushi.com/recipes/1').to_return_json(result: { id: 1, user_id: "1" } )
      stub_request(:get, 'http://sushi.com/recipes/2').to_return_json(result: { id: 2, user_id: nil } )
      stub_request(:get, 'http://sushi.com/users/1').to_return_json(result: { id: 1 })

      recipe = Recipe.find(1)
      assert_equal 1, recipe.user.id

      recipe = Recipe.find(2)
      assert_nil recipe.user
    end

For recipe with ID 1, the user is known and retrievable. For recipe with ID 2, the user is unknown and no retrieval attempt should be made instead of throwing the exception. This should be analogue to when the data would have been embedded, nil or as { uuid: 1, name: "paulvt", ... }

@balvig
Copy link
Owner

balvig commented Dec 22, 2017

@paulvt aha I see!

Thanks, the test makes it a lot clearer, I've started a branch here.

@balvig
Copy link
Owner

balvig commented Dec 22, 2017

@paulvt not sure if the approach I'm taking in https://github.com/balvig/spyke/compare/belongs_to is the best yet, but could you maybe give it a try to see if it solves your problem?

@paulvt
Copy link
Author

paulvt commented Jan 3, 2018

Yeah, I already had an inkling that the URL was constructed before checking if the necessary attributes, in this case the primary key, were present. So, this seems good. I have also tested with the branch and this indeed fixes the problem!

@balvig
Copy link
Owner

balvig commented Jan 5, 2018

Awesome, thanks @paulvt! I will do some more testing and then look to releasing a new version.

@balvig balvig closed this as completed in #92 Feb 2, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants