-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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
Add queryOne method #2584
Add queryOne method #2584
Conversation
I still need to write some tests, but there are quite a few to write so I just want to be sure this is the way we want to implement |
We should always fetch fresh data, same as findQuery does. |
I think it would be useful for this could be made to work without requiring an id to solve issues like #2558. |
@igorT just pushed some tests, let me know what you think |
@thaume sorry for not getting back to you sooner. Can you please rebase? I think this looks great for now. I hope we can figure out a way in the future to also allow easy passing of a custom URL and not just options. |
93d4787
to
f8e6dbf
Compare
@igorT no problem man, the rebase is done! Let me know if you want me to open another PR to keep working on it or if it can wait! |
21be80a
to
5758e7a
Compare
This should solve #1576 |
#1326, which is closed, will also be solved by this pull request. |
+1 on this feature. This is useful for cases like getting something by a slug instead of id (the slug is considered unique in some cases, so it's like getting by id, but needs to use a query params). Having said that, it's not really hard to workaround this. However, it seems that in the extractQueryOne, you assume that there is only one resource, however I think it should call extractArray instead of extractSingle. The reason is that while you EXPECT only one record from your server, you are still hitting a "collection URI", not a single item URI. |
@bakura10 I don't think you'd use this method to get records through slugs, since you need to use an id to fetch. |
What I mean by collection URI is "/users", while "item URI" is "/users/5". "/users" is expected to return a collection, so "/users?first_name=foo" is expected to return a collection too, as well as "/users?slug=bar", but in my case, as slug are unique, I can guarantee myself that I will return at most 1 element, but as this is still a collection URI, I return it as a collection (so wrapped with a "users" in plural). It would feel very strange for me to have a collection URI return things that is not a collection. |
Yes totally agree with you, but fetchQueryOne will issue a request of the Le mar. 10 févr. 2015 22:53, Michaël Gallego notifications@github.com a
|
Haaa... Ok, I misunderstood the issue then. I thought it was actually made for use cases like a query is expected to return only one result. Sorry sorry, definitely a good idea then, I see the use case now! :) |
@param {any} query an opaque query to be used by the adapter | ||
@return {Promise} promise | ||
*/ | ||
findQueryOne: function(typeName, id, query) { |
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'd be in favor of renaming the store api to fetchQueryOne
since it looks like this will always fetch a new record. Keeping the adapter API as findQueryOne
seems fine and consistent with the other adapter methods.
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.
Then you would also rename findQuery
-> fetchQuery
?
Relevant: emberjs/rfcs#27 |
Marked this for discussion at tomorrow's Ember Data meeting. |
@@ -745,7 +745,7 @@ export default Ember.Object.extend({ | |||
call is made to `DS.Store#findQuery`. By default this method is an | |||
alias for [extractArray](#method_extractArray). | |||
|
|||
@method extractFindQuery | |||
@method extractFindQueryOne |
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.
Looks like this should stay as extractFindQuery
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.
Good catch! I Guess I mixed names while changing from findQuery
to findQueryOne
. Thanks :)
5758e7a
to
be59fd4
Compare
@igorT juste need to squash and we're good to go |
260430b
to
6c6d3e6
Compare
@igorT commits squashed ! Thanks for the review ! |
})); | ||
}); | ||
|
||
ok(!store.hasRecordForId('person', 1), "The record has been unloaded"); |
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.
Why is this id 1?
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.
Yep that was an old test from the "fetchQueryOne" method which worked with an id, removing the test
6c6d3e6
to
a1ed12f
Compare
a1ed12f
to
5e39cbc
Compare
Thanks! |
I'm confused. I thought queryRecord mentioned here enables something like (For context, my question stems from #3454). Thanks! |
That was the old implementation. Now you cannot pass an id to queryRecord,
|
this must be the most confusing PR i have ever seen! Can somebody clarify how to make what @allthesignals is asking for is supposed to work? |
@Fryie feel free to ping me in the Ember Community Slack, happy to help |
@wecc what's the solution you came up with? |
The conversation which helped @hunterboerner for the record
|
@igorT why is all this so complicated? |
I agree. This is a very simple use case. There is no way I want to send a request like When you are dealing with a database that has hundreds of millions of records, your 10 ms query could turn into a few seconds. From an API side, most programmers don't look to see if the id is one of the many possible query params. That means if your default query limit for a GET list is 20 records, the DB Engine will search for a 'like' match to the id query param until it a) finds its 20 matches or b) reaches the end of the table. Where as a query looking for a single record sets limit to 1 and returns an exact match as soon as it finds the indexed record. Big performance difference on the db. Luckily for me I have control over the API that I am connecting to with Ember. |
@jeffjarchow I now use a solution provied by @igorT: export default DS.JSONAPIAdapter.extend({
urlForFindRecord(id, modelName, snapshot) {
let url = this._super(...arguments);
let query = Ember.get(snapshot, 'adapterOptions.query');
if (query) {
url += '?' + Ember.$.param(query); // assumes no query params are present already
}
return url;
}
});
this.store.findRecord('project', params.project_id, {adapterOptions: {query: {include: 'user,developer', limit: 1}}}); This works, but so hacky :( |
Thank you @terion-name for the snippet. I'll have to play with that to see if I can get that working. I would just be afraid of it not being compatible as things change. Currently I am on a major upgrade from 1.10 to 1.13 and all the changes that go along with that, like eliminating views. |
@terion-name, U rock. |
For anyone else finding this, since Ember 2.4 it's built in: ds-finder-include
|
The findQueryOne method let developers query their server-side API for a single record and also pass a query parameter to this call.
For instance, you could do the following: