-
Notifications
You must be signed in to change notification settings - Fork 19
added type parameter to the relations #36
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
Conversation
The type parameter is necessary to choose the service build the right resources. The type is not always the same as the relation name.
|
I'll take a look tomorrow, thanks. |
|
@Rahien yeah I see how the type value helps when the reasource name is not the same as the type. I'm wondering about how to set that up so it's clearly documented, for example: vs. so instead of two parameters there would still be one parameter passed to Any thoughts? |
the relations now accept either a string or an object. the object holds
the specification of the relationship in the format:
hasMany( { resource: "friends",
type: "persons" } )
If the type of the relationship is the same as the name of the
relationship, type can be omitted in the specification object.
Passing
hasMany( "persons" )
is the same as
hasMany( { resource: "persons",
type: "persons" } )
|
Yes! That makes a lot of sense, I changed it in the latest commit. |
|
@Rahien I'm trying to figure out a test case for this usage of a resource with a different type name. do you have any JSON examples you can share from your API? Are you using JSONAPI::Resources gem? |
|
@Rahien I think your use case is that a service may be named 'persons' which can return various resource types, e.g. Children and Friends. And, those types are relation names as well. But when used as a relation only the 'persons' service (endpoint) is used to find the resources. This use case seems doable but it will require some extra setup when generating resources with the ember-cli generator tool. You'll need to generate a model for the Child and Friend types; but not services using those resource names (children and friends services/endpoints do not exist, only persons). And, you may need to generate a 'persons' resource - which may only be an abstract model used when extending to create Child or Friend resources (model prototypes). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm curious if 'promise': promise, 'type': relation would also need to change to 'promise': promise, 'type': type ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From what I can tell, the type parameter on line 398 is not used at the moment, but I am probably missing something here...
|
I'd like to create a test to accompany this pull request but am not familiar with how your app is using this optional resource/type value for using a common server for various resources. I'd need some JSON docs and a the resource (model) prototypes to setup a test. |
|
Let me start by thanking you for all your help! Now, the actual use case that I am trying to solve is the front end of a taxonomy matching service. A user receives a list of topics and the topics have mappings to topics of another taxonomy. These mappings are directional and receive a match type selected by the user, e.g. exact, close, narrow, broad (the last two explain why the match is directional). So, the mappings have two relationships to topics, a "from" and a "to" relation, both pointing to a resource of the kind "topic". There is no reason to use a different model or service to instantiate these resources (though I can see how polymorphic relations could be challenging). In my case both relations are of the type "topic", but they have different names and different semantics. Here is an example json file that is returned by the back end that I am using (generated by https://github.com/mu-semtech/mu-cl-resources), this returns the list of mappings for a topic: the topics themselves have the following resource file (coffeescript): So there are two hasOne relations with the same type "topic". This was previously impossible as the name of the resource was assumed to be the same as the topic. Is there anything else that is still unclear in the use case? |
|
@Rahien I did some work to figure out what is needed to support polymorphic associations, see #37 however that is not directly related to your use case.
These reference relations I am still curious if just creating a service (which uses the application adapter and serializer) for the I'm wondering what would be best… A) to have a simple service that is used only for the findRelated adapter method for every relation (no need to add extra configuration) Or, B) to provide the proposed options to provide a type that is used for the service when the relation is fetched via the service#findRelated call. |
|
hey guys, fwiw, I had a similar case where the same entity could be of a different type when in a relationship. In it a I got bit by EJR not accepting a type and relation names being different, and almost posted a feature request here as well. But then decided to try and solve this on the backend, by having different endpoints and resources for these relationships. So, in rails, the This clicked for me, seems intuitive to have the same resources defined on the front end and backend, instead of having to translate the types so a front-end resource maps to a different one on the backend. Makes it easy for the front-end to decide what resources it needs. Also gave me the freedom to return different payload for each of the resource representations on the backend. This assumes one has control of the API, though, to keep the resource modeling in sync between the two. I'm not sure what the JSONAPI authors think about the common enough scenario of front-end devs having to adapt to APIs that don't map to their local modeling. My impression is the philosophy has been for the front-end to drive the API design from the beginning? |
|
@Rahien one more thing I am curious about… in your use case will the export default ApplicationAdapter.extend({
type: 'from',
url: '/topics',
fetchUrl: function(url) {
/* manipulate if needed */
return url;
}
}); |
|
Hmmm regarding the url, indeed at the moment the type of both relations is always 'topic'. I see what you mean, for every relation, you would create an adapter and a service. I guess that works, but isn't the overhead of defining an extra adapter and service every time a bit much? It does away with extra configuration options being passed in, but there is so much extra code involved when using it... Just referring to an existing service in the model seems less confusing to me. Still: personal opinion, so it's your call of course! |
|
@Rahien I agree it's a nice option to specify another type as an alias for a relation. I just needed to better understand the use case so I could come up with a test for it. I'll work on adding a test. |
The type parameter is necessary to choose the service build the right
resources. The type is not always the same as the relation name.
For instance say there is a Person that has a relationship called 'friends' to other Persons and a relationship called 'children' to other Persons as well. The specification in the resource would now be:
The previously you would get an exception when the name of the relation was not the same as the type.
The type is now the second argument in the specification of the relation in the resource, but it is optional. If the type is indeed the same as the relation name, it can be omitted.