You cannot load dependent objects for more than 1000 resources. Use a filter to restrict your query - csom

I am trying to do something that I thought would be really simple - get a single assignment of a single enterprise resource.
My code is this:
var resource = ctx.EnterpriseResources.GetByGuid(resourceId);
ctx.Load(resource);
ctx.ExecuteQuery();
var assignment = resource.Assignments.GetByGuid(assignmentId);
ctx.Load(assignment);
ctx.ExecuteQuery();
But when I run this, I get the following error:
Too many resources: 2643. You cannot load dependent objects for
more than 1000 resources. Use a filter to restrict your query.
The error is also described here https://social.technet.microsoft.com/Forums/azure/en-US/4fab5f62-5955-4257-af0f-a5e1fa58dca7/error-reading-project-custom-fields-via-csom-too-many-projects?forum=projectonline
But I do not understand why we get this error. We get a single resource and we try to get a single assignment for it - why does it complain about affecting more than 1000 (2643) resources?
Thanks :-)

Related

URL Structure for Comparing Items

What is the best way to structure a route for comparing multiple items?
Here's the URL example: https://versus.com/en/microsoft-teams-vs-slack-vs-somalia
How to achieve this in routes.rb file? Cannot really find anything in Internet regarding ruby gems. The only thing I can think about is url with optional params, however what if the number of params is unlimited?
you're going to have to parse the a-vs-b-vs-c yourself.
So in routes.rb, you'll have something like:
get 'compare/:compare_string', to 'compare#show'
then you'll get a parameter compare_string that you'll have to parse:
#in compare_controller.rb
def show
compare_items = params[:compare_string].split('-vs-')
# generate the comparison from the compare_items array
end
First - you probably shouldn't allow unlimited #'s of parameters in practice. Even something like 100 might break your page and/or cause performance issues and open you up to DOS attacks. I'd choose some kind of sensible/practical limit and document/enforce it (like 10, 12 or whatever makes sense for your application). At around 2k characters you'll start running into URL-length issues.
Next - is there any flexibility in the URL? Names tend to change so if you want URL's to work over time you'll need to slug-ify each of them (with something like friendly-id) so you can track changes over time. For example - could you use an immutable/unique ID AND human-readable names?
In any case, Rails provides a very flexible system for URL routing. You can read more about the various options / configurations with their Rails routing documentation.
By default a Dynamic Segment supports text like in your example, so (depending on your controller name) you can do something like:
get 'en/:items', to: 'items#compare'
If it's helpful you can add a custom constraint regexp to guarantee that the parameter looks like what you expect (e.g. word-with-dashes-vs-another-vs-something-else)
get 'en/:items', to: 'items#compare', constraints: { items: /(?:(?:[A-Z-]+)vs)+(?:[A-Z-]+)/ }
Then, in your controller, you can parse out the separate strings however you want. Something like...
def compare
items = params[:items].split('-vs-')
end

How to add attribute/property to each record/object in an array? Rails

I'm not sure if this is just a lacking of the Rails language, or if I am searching all the wrong things here on Stack Overflow, but I cannot find out how to add an attribute to each record in an array.
Here is an example of what I'm trying to do:
#news_stories.each do |individual_news_story|
#user_for_record = User.where(:id => individual_news_story[:user_id]).pluck('name', 'profile_image_url');
individual_news_story.attributes(:author_name) = #user_for_record[0][0]
individual_news_story.attributes(:author_avatar) = #user_for_record[0][1]
end
Any ideas?
If the NewsStory model (or whatever its name is) has a belongs_to relationship to User, then you don't have to do any of this. You can access the attributes of the associated User directly:
#news_stories.each do |news_story|
news_story.user.name # gives you the name of the associated user
news_story.user.profile_image_url # same for the avatar
end
To avoid an N+1 query, you can preload the associated user record for every news story at once by using includes in the NewsStory query:
NewsStory.includes(:user)... # rest of the query
If you do this, you won't need the #user_for_record query — Rails will do the heavy lifting for you, and you could even see a performance improvement, thanks to not issuing a separate pluck query for every single news story in the collection.
If you need to have those extra attributes there regardless:
You can select them as extra attributes in your NewsStory query:
NewsStory.
includes(:user).
joins(:user).
select([
NewsStory.arel_table[Arel.star],
User.arel_table[:name].as("author_name"),
User.arel_table[:profile_image_url].as("author_avatar"),
]).
where(...) # rest of the query
It looks like you're trying to cache the name and avatar of the user on the NewsStory model, in which case, what you want is this:
#news_stories.each do |individual_news_story|
user_for_record = User.find(individual_news_story.user_id)
individual_news_story.author_name = user_for_record.name
individual_news_story.author_avatar = user_for_record.profile_image_url
end
A couple of notes.
I've used find instead of where. find returns a single record identified by it's primary key (id); where returns an array of records. There are definitely more efficient ways to do this -- eager-loading, for one -- but since you're just starting out, I think it's more important to learn the basics before you dig into the advanced stuff to make things more performant.
I've gotten rid of the pluck call, because here again, you're just learning and pluck is a performance optimization useful when you're working with large amounts of data, and if that's what you're doing then activerecord has a batch api you should look into.
I've changed #user_for_record to user_for_record. The # denote instance variables in ruby. Instance variables are shared and accessible from any instance method in an instance of a class. In this case, all you need is a local variable.

Multiple nesting in Falcor query

I am trying to query a multiple nested object with Falcor. I have an user which has beside other the value follower which itself has properties like name.
I want to query the name of the user and the first 10 follower.
My Falcor server side can be seen on GitHub there is my router and resolver.
I query the user with user["KordonDev"]["name", "stars"]. And the follower with user["KordonDev"].follower[0.10]["name", "stars"].
The route for follower is user[{keys:logins}].follower[{integers:indexes}] but this doesn't catch the following query.
I tried to add it as string query.
user["KordonDev"]["name", "stars", "follower[0..10].name"] doesn't work.
The second try was to query with arrays of keys. ["user", "KordonDev", "follower", {"from":0, "to":10}, "name"] but here I don't know how to query the name of the user.
As far as I know and looking on the path parser. There is no way to do nested queries.
What you want to do is batch the query and do two queries.
user["KordonDev"]["name", "stars"]
user["KordonDev"]["follower"][0..10].name
It seems that falcor does not support this, there is even a somewhat old issue discussing how people trying to do nested queries.
to the point about the current syntax leading people to try this:
['lolomo', 0, 0, ['summary', ['item', 'summary']]]
I can see folks trying to do the same thing with the new syntax:
"lolomo[0][0]['summary', 'item.summary']"
As soon as they know they can do:
"lolomo[0][0]['summary', 'evidence']"
So it seems deep nested queries is not a functionality.

Rails get last X objects with attribute match

I have a model DeferredHost, which also has an attribute ignore_flag. At the present, I'm just getting all of the deferred hosts in my controller:
#deferred_hosts = #company.deferred_hosts.last(5)
However, I'd like to make it subjective and only get the last 5 deferred hosts that have the ignore_flag = true.
How can I go about doing this? Should I use an if statement and loop through each deferred host, or is there a more 'Rails' way?
You can use where to make the query more specific:
#deferred_hosts = #company.deferred_hosts.where(ignore_flag: true).last(5)

How to perform #find on an object without Active Model

Here's what's happend: I have gone and pulled a large amount of data from an API. This is nice, but it includes a lot of results.
When I do a result.find(id: api_id) I get all the results like find was never performed. #where does not work either. I'm assuming this is because its not extending from Active Model.
Key Question: How do I find, say, the name of a particular object in an active resource collection?
Object.find(id: api_id) in active resource is essentially doing an api request as in (uri_of_api)/objects/:api_id)
But the :find method on an array is a different aninmal. You can look up the array 'find' method here... http://www.ruby-doc.org/core-2.1.1/Enumerable.html#method-i-find
The correct format would be...
result.find{|rec| rec.id == api_id}

Resources